[javascript] clone()


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์ฐจ์› ๋ฐฐ์—ด์˜ ๊นŠ์€ ๋ณต์‚ฌ

  1. ์ด์ค‘ 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;
    }
}