반응형
자바에는 얕은 복사 (Shallow Copy) 와 깊은 복사 (Deep Copy) 가 존재한다.
얕은 복사는 복사하려는 배열의 '주소값'을 복사함
깊은 복사는 '실제값'을 새로운 메모리 공간에 복사함
1차원 배열
- 얕은 복사
- 복사하려는 배열의 주소값을 가져옴
- 두 개의 배열 중 하나라도 값을 수정한다면 둘 다 수정됨
int[] A = {1, 2, 3};
int[] B = A;
B[0] = 5;
A[2] = 10;
System.out.println(A[0]); // 5
System.out.println(B[2]); // 10
B[0]을 수정했지만 A[0]의 값도 변경되고, A[2]를 수정했지만 B[2]의 값도 같이 변하는 것을 볼 수 있다.
- 깊은 복사
- 복사하려는 배열의 주소값이 아닌 실제값을 가져와서 새로운 메모리 공간에 복사함
- 두 개의 배열이 서로 영향을 받지않음
int[] A = {1, 2, 3};
int[] B = A.clone();
B[0] = 5;
A[2] = 10;
System.out.println(A[0]); // 1
System.out.println(B[2]); // 3
B[0]을 수정했지만 A[0]의 값에는 영향이 없는 것을 확인할 수 있다. B 배열 또한 A 배열에 영향이 없다.
2차원 배열
- 얕은 복사
int[][] A = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int[][] B = A.clone();
B[0][0] = 5;
A[2][2] = 10;
System.out.println(A[0][0]); // 5
System.out.println(B[2][2]); // 10
1차원 배열에서의 A.clone() 은 깊은 복사가 되었지만 2차원 배열에서 사용하게 되면 얕은 복사가 된다. 즉, B 배열의 값을 변경하게 되면 A 배열의 값도 같이 변한다.
- 깊은 복사
- 2중 반복문
- 반복문 + System.arraycopy(복사하려는 배열, 복사하려는 배열의 시작 위치, 새 배열, 새로운 배열의 시작 위치, 길이)
int[][] A = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int[][] B = new int[3][3];
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
B[i][j] = A[i][j];
}
}
B[0][0] = 5;
A[2][2] = 10;
System.out.println(A[0][0]); // 1
System.out.println(B[2][2]); // 9
int[][] C = new int[3][3];
for (int i=0; i<3; i++) {
System.arraycopy(A[i], 0, C[i], 0, 3);
}
A[1][1] = 15;
C[1][2] = 10;
System.out.println(C[1][1]); // 5
System.out.println(A[1][2]); // 6
2차원 배열에서는 두 가지 방법으로 깊은 복사를 할 수 있다.
객체 배열
- 얕은 복사
public static class Pos {
int x, y;
public Pos (int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
Pos[] A = new Pos[3];
for (int i=0; i<3; i++) {
A[i] = new Pos(i, i);
}
Pos[] B = A;
B[0].x = 5;
B[0].y = 5;
Pos[] C = new Pos[3];
for (int i=0; i<3; i++) {
C[i] = A[i];
}
C[1].x = 10;
C[1].y = 10;
Pos[] D = new Pos[3];
System.arraycopy(A, 0, D, 0, A.length);
D[2].x = 20;
D[2].y = 20;
System.out.println(A[0].x + " :: " + A[0].y); // 5 :: 5
System.out.println(A[1].x + " :: " + A[1].y); // 10 :: 10
System.out.println(A[2].x + " :: " + A[2].y); // 20 :: 20
}
- 깊은 복사
public static class Pos {
int x, y;
public Pos (int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
Pos[] A = new Pos[3];
for (int i=0; i<3; i++) {
A[i] = new Pos(i, i);
}
Pos[] B = A.clone();
B[0] = new Pos(5,5);
Pos[] C = new Pos[3];
for (int i=0; i<3; i++) {
C[i] = new Pos(A[i].x, A[i].y);
}
C[1].x = 10;
C[1].y = 10;
Pos[] D = new Pos[3];
System.arraycopy(A, 0, D, 0, A.length);
D[2] = new Pos(20, 20);
System.out.println(A[0].x + " :: " + A[0].y); // 0 :: 0
System.out.println(A[1].x + " :: " + A[1].y); // 1 :: 1
System.out.println(A[2].x + " :: " + A[2].y); // 2 :: 2
}
객체 배열에서의 얕은 복사와 깊은 복사의 차이점은 배열의 값을 변경하거나 선언할 때 new 생성자의 유무이다. 얕은 복사에서는 new 생성자를 사용하지 않았고, 깊은 복사에서는 복사할 배열을 선언할 때, 값을 변경할 때 new 생성자를 사용했다.
반응형
'개발 & 데이터베이스 > JAVA' 카테고리의 다른 글
자바 Comparable과 Comparator 차이점 (0) | 2023.02.08 |
---|---|
자바 오류 source release 11 requires target release 11 해결 (0) | 2023.01.12 |
자바 String, StringBuffer, StringBuilder 차이 (0) | 2022.11.12 |
자바 정적 (Static) 메서드 정의 및 생성, 사용 예시 (0) | 2022.11.08 |
자바 파일 복사하는 4가지 방법 (0) | 2022.10.14 |