[javascript] clone()
in JavaScript
clone()
๋ฐฐ์ด์ ๋ณต์ฌ์ ๊ด๋ จํด์๋ ์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ์ ์ฐจ์ด์ ์ ์์์ผ ํ๋ค.
์์ ๋ณต์ฌ(shallow copy)
ํ ์ชฝ์์ ์์ ์ด ๋ฐ์๋๋ฉด ๋ค๋ฅธ์ชฝ์๋ ์ํฅ์ ๋ผ์ณ ๊ฐ์์ง๊ฒ ๋๋ค.
- ๊ฐ๋ฅํ ์ด์ ๋ ์์ ๋ณต์ฌ๊ฐ ์ฃผ์๊ฐ์ ๋ณต์ฌํ๊ธฐ ๋๋ฌธ์ ์ฃผ์๋ก ๊ฐ์ ์ฐธ์กฐํ์ฌ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ํด๋น ๊ฐ์ ์ฐธ์กฐํ๊ณ ์๋ ๋ฐฐ์ด๋ค์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค.
- ์ฆ, ๋ณต์ฌ๋ ๋ฐฐ์ด์ด๋ ์๋ณธ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋ ๋, ํจ๊ป ๋ณ๊ฒฝ๋๋ค. = ์ฐ์ฐ์๋ ์์ ๋ณต์ฌ๋ฅผ ์ํํ๋ค.
int[] a = new int[2];
a[0] = 2;
a[1] = 4;
int[] b = a;
b[0] = 6;
b[1] = 8;
System.out.println(a[0]+", "+a[1]);
System.out.println(b[0]+", "+b[1]);
// ๊ฒฐ๊ณผ
6, 8
6, 8
- ์์ ์ฝ๋์ฒ๋ผ 1์ฐจ์ ๋ฐฐ์ด์ = ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด ์์ ๋ณต์ฌ๋ฅผ ์งํํ๊ฒ ๋๋ฉด ๋ณต์ฌ๋ ๋ฐฐ์ด์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋, ์๋ณธ ๋ฐฐ์ด์ ๊ฐ๋ ๋ณ๊ฒฝ๋๋ค.
- 2์ฐจ์ ๋ฐฐ์ด๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค. ๋ค์ ์ฝ๋๋ฅผ ๋ณด์.
int[][] a = new int[2][2];
int[][] copy = a;
copy[0][0] = 1;
for (int[] aa : a) {
for (int v : aa) System.out.print(v + " ");
System.out.println();
}
System.out.println();
for (int[] aa : copy) {
for (int v : aa) System.out.print(v + " ");
System.out.println();
}
// ๊ฒฐ๊ณผ
1 0
0 0
1 0
0 0
- = ์ฐ์ฐ์๋ฅผ ์ด์ฉํด 2์ฐจ์ ๋ฐฐ์ด์์ ์์ ๋ณต์ฌ๊ฐ ์ด๋ค์ก๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น? ๊น์ ๋ณต์ฌ๋ฅผ ์ฌ์ฉํ์!
๊น์ ๋ณต์ฌ(Deep copy)
- ๊น์ ๋ณต์ฌ๋ ์ฃผ์๊ฐ์ ์ฐธ์กฐํ๋ ๊ฒ์ด ์๋, ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์๋ณธ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋์ด๋ ๋ณต์ฌ๋ ๋ฐฐ์ด์ ์ ํ ์๊ด์ด ์๋ค.
- ๋ฐ๋ผ์ ๋ฐฐ์ด์ ๋ณต์ฌํ ํ์ ํ์ชฝ ๊ฐ์ ์์ ํด๋ ๋ค๋ฅธ ๋ฐฐ์ด์ ์ํฅ์ ๋ผ์น์ง ์๋๋ค.
1) 1์ฐจ์ ๋ฐฐ์ด์ ๊น์ ๋ณต์ฌ
- 1์ฐจ์ ๋ฐฐ์ด์ ๊น์ ๋ณต์ฌ๋ ๋ฐฐ์ด.clone() ํจ์๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ๋จํ๊ฒ ํ ์ ์๋ค.(์ผ๋ฐ ์๋ฃํ์ ๊ฒฝ์ฐ)
- ํน์ ๊ฐ๋จํ๊ฒ for๋ฌธ์ ๋๋ฉฐ ๋ฃ์ด์ค๋ ๋๋ค.
public static void main(String[] args) {
int[] arr = new int[10];
int[] copy = deepCopyWithClone(arr);
for (int i = 0; i < arr.length; i++) arr[i] = i;
for (int a : arr) System.out.print(a + " ");
System.out.println();
copy[0] = 100;
for (int a : copy) System.out.print(a + " ");
}
private static int[] deepCopyWithClone(int[] original) {
if (original == null) return null;
int[] result = new int[original.length];
result = original.clone();
return result;
}
// ๊ฒฐ๊ณผ
0 1 2 3 4 5 6 7 8 9 -> arr
100 0 0 0 0 0 0 0 0 0 -> copy
- ๊ฐ์ฒด ๋ฐฐ์ด์ ๊ฒฝ์ฐ,
.clone()
์ ์ฌ์ฉํ๋ฉด ๊น์ ๋ณต์ฌ๊ฐ ์๋๋ค. ์ด์ ๋ ๊ฐ์ฒด๋ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก 2์ฐจ์ ๋ฐฐ์ด์ ๊ฒฝ์ฐ๋ ๊ฐ๊ฐ row์ ๋ํ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ deepCopy๊ฐ ์๋๋ค.
2) 1์ฐจ์ ๊ฐ์ฒด ๋ฐฐ์ด์ ๊ฒฝ์ฐ, ๊น์ ๋ณต์ฌ
private static void ObjectArray() {
Position[] pos = new Position[10];
for (int i = 0; i < pos.length; i++) pos[i] = new Position(i, i);
Position[] copy = deepCopy(pos);
copy[0].a = 100;
copy[0].b = 200;
for (int i = 0; i < pos.length; i++) {
System.out.print("(" + pos[i].a + ", " + pos[i].b + ")");
}
System.out.println();
for (int i = 0; i < copy.length; i++) {
System.out.print("(" + copy[i].a + ", " + copy[i].b + ")");
}
}
private static Position[] deepCopy(Position[] original) {
if (original == null) return null;
Position[] result = new Position[original.length];
for (int i = 0; i < result.length; i++) result[i] = new Position(original[i].a, original[i].b);
return result;
}
// ๊ฒฐ๊ณผ
(0, 0)(1, 1)(2, 2)(3, 3)(4, 4)(5, 5)(6, 6)(7, 7)(8, 8)(9, 9)
(100, 200)(1, 1)(2, 2)(3, 3)(4, 4)(5, 5)(6, 6)(7, 7)(8, 8)(9, 9)
- ์ด์ฒ๋ผ 1์ฐจ์ ๊ฐ์ฒด ๋ฐฐ์ด์ ๋ณต์ฌํ๊ธฐ ์ํด์๋ for๋ฌธ์ ๋๋ฉฐ ๋ฃ์ด์ฃผ๋๋ฐ ์ด๋๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ new๋ก ์์ฑํ๋ฉฐ ์ง์ ๊ฐ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. ๊ทธ๋์ผ ๋ค๋ฅธ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ด์ ๋ฐฐ์ด๋ก ๋ณต์ฌ๋ ๋ฐฐ์ด์ ๊ฐ์ง ์ ์๋ค.
3) 2์ฐจ์ ๋ฐฐ์ด์ ๊น์ ๋ณต์ฌ
- ์ด์ค for๋ฌธ์ ์ํํ๋ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ ์๋ฃํ์ธ ๊ฒฝ์ฐ, ๊ฐ๋จํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
private static void TwoArrayDeepCopy() {
int[][] arr = new int[5][5];
int[][] copy = deepCopyTwoArray(arr);
arr[0][0] = 1;
copy[0][1] = 2;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println();
for (int i = 0; i < copy.length; i++) {
for (int j = 0; j < copy.length; j++) {
System.out.print(copy[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
private static int[][] deepCopyTwoArray(int[][] original) {
if (original == null) return null;
int[][] result = new int[original.length][original.length];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result.length; j++) {
result[i][j] = original[i][j];
}
}
return result;
}
// ๊ฒฐ๊ณผ
// arr
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
// copy
0 2 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
- ์ด์ฒ๋ผ ๊ฐ์ ์ง์ ๋ฃ์ด์ค๋ deepCopy๊ฐ ์๋๋ค. ๋ฐฐ์ด์ ๋ณต์ฌํ ์ดํ, ๋ณต์ฌํ ๋ฐฐ์ด์ ๊ฐ์ ๋ณ๊ฒฝํด๋ ์๋ ๋ฐฐ์ด์ ์ํฅ์ ๋ผ์น์ง ์๋ ๊น์ ๋ณต์ฌ๊ฐ ์ ์ด๋ฃจ์ด์ก๋ค.
2.System.arraycopy๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ ์๋ฃํ์ธ ๊ฒฝ์ฐ, ์๋ ์ฝ๋์ฒ๋ผ System.arraycopy ๋ฉ์๋๋ฅผ ์ด์ฉํด 2์ฐจ์ ๋ฐฐ์ด์ ๋ณต์ฌํ ์ ์๋ค.
- 1์ฐจ์ ๋ฐฐ์ด์ 2์ฐจ์ ๋ฐฐ์ด์ row ๊ธธ์ด๋งํผ ๋ณต์ฌํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
- 1๋ฒ์์ ์ฌ์ฉํ ๋ฐฐ์ด๊ณผ ๊ฐ์ ๋ฐฐ์ด์ ์ฌ์ฉํ๋ค.
private static int[][] deepCopyUseSystemArrayCopy(int[][] original) {
if (original == null) return null;
int[][] result = new int[original.length][original.length];
for (int i = 0; i < result.length; i++) {
System.arraycopy(original[i], 0, result[i], 0, original[i].length);
}
return result;
}
// ๊ฒฐ๊ณผ
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 2 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1๋ฒ๊ณผ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ด๋ฉฐ, deepCopy๊ฐ ์ด๋ฃจ์ด์ก์์ ํ์ธํ ์ ์๋ค.
4) 2์ฐจ์ ๊ฐ์ฒด ๋ฐฐ์ด์ ๋ณต์ฌ
- 2์ฐจ์ ๊ฐ์ฒด ๋ฐฐ์ด์ ๋ณต์ฌ๋ฅผ ํ ๊ฒฝ์ฐ, arraycopy๋ clone์ ์ด์ฉํด์ ๋ณต์ฌํ ์ ์๋ค.
- ๊ทธ๋์ for๋ฌธ์ ๋๋ฉด์ ๊ฐ์ ์ง์ ๋ณต์ฌํ๋ฉฐ, ๊ฐ์ฒด๋ฅผ ์๋ก ์์ฑํด์ผ ํ๋ค.
public static void main(String[] args) {
Position[][] positions = new Position[3][3];
for (int i = 0; i < positions.length; i++) {
for (int j = 0; j < positions[i].length; j++) {
positions[i][j] = new Position(i, j);
}
}
Position[][] copy = deepCopy(positions);
copy[0][0].a = 100;
copy[0][1].b = 200;
positions[0][0].a = 2;
positions[0][0].b = 2;
print(positions);
print(copy);
}
public static void print(Position[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
Position pos = arr[i][j];
System.out.print("(" + pos.a + ", " + pos.b + ") ");
}
System.out.println();
}
System.out.println();
}
// for๋ฌธ์ ๋๋ฉด์ ๊ฐ์ ์ง์ ๋ณต์ฌํ๋ฉฐ ๊ฐ์ฒด๋ฅผ ์๋ก ์์ฑํ๋ค.
private static Position[][] deepCopy(Position[][] original) {
if (original == null) return null;
Position[][] result = new Position[original.length][original.length];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
result[i][j] = new Position(original[i][j]);
}
}
return result;
}
static class Position {
int a;
int b;
Position(int a, int b) {
this.a = a;
this.b = b;
}
// ๋ณต์ฌ๋ฅผ ์ํ ์์ฑ์.
Position(Position position) {
this.a = position.a;
this.b = position.b;
}
}