ultra_dev
배열 <깊은 복사, 얕은 복사> 본문
깊은 복사(Deep Copy)는 '실제 값'을 새로운 메모리 공간에 복사하는 것을 의미하며, 복사된 배열이나 원본배열이 변경될 때 서로 간의 값은 바뀌지 않음
(복사값을 바꿔도 원본값 안바뀜)
얕은 복사(Shallow Copy)는 '주소 값'을 복사한다는 의미하며, 복사된 배열이나 원본배열이 변경될 때 서로 간의 값이 같이 변경됨
(복사값을 바꿨는데 원본값도 바뀜)
얕은 복사의 경우 주소 값을 복사하기 때문에, 참조하고 있는 실제값은 같음
→ 알고리즘 문제 풀 때 얕은 복사 하다가 원본값도 바껴서 오류 날 수 있으니 조심!!
❗얕은 복사,깊은 복사 (1차 배열과 2차 배열에서 깊은 복사 가능한 메소드가 다름)
📋<1차 배열>
- 1차 배열에서 얕은 복사
📌 (=)
int[] arr = {1,2,3};
int[] copy = arr;
copy[1] = 3;
->int[] arr = {1,3,3}
->int[] copy = {1,3,3}
즉, copy 배열 수정하면 arr배열도 수정 돼버리는 어이 없는 상황 발생
→ 얕은 복사는 주소 값을 복사하기 때문에 복사 값을 바꾸면 원본값도 바껴버림!!
- 1차 배열에서의 깊은 복사
📌 **.clone()**
<int[] arr = {1,2,3};
int[] copy = arr.clone();
copy[1] = 3;
-> int[] arr = {1,2,3}
-> int[] copy = {1,3,3}
📌 System.arraycopy()
int[] arr = {1,2,3};
int[] copy = new int[arr.length];
System.arraycopy(arr, 0, copy, 0, 3);
//원본배열, 원본배열 복사 시작 인덱스,새 배열,새 배열 붙여넣기 시작 인덱스,복사 항목 수
copy[1] = 3;
-> int[] arr = {1,2,3}
-> int[] copy = {1,3,3}
📌 for문으로 직접 돌아가며 찍기(어느 상황에서든 제일 확실)
int[] arr = {1,2,3};
int[] copy = new int[3];
for(int i=0; i<arr.length; i++) {
copy[i] = arr[i];
}
copy[1] = 3;
-> int[] arr = {1,2,3}
-> int[] copy = {1,3,3}
📋<2차 배열>
- 2차 배열에서의 얕은 복사 (💥for문 포함 안되면 전부 얕은 복사)
일어나는 이유 :
객체 배열의 경우 각각 주소값을 가지고 있기 때문에 깊은 복사가 안되는 것!!
arr[x][y]에서
arr[x]부분까지만 깊은 복사가 되고 arr[x][y] 부분은 깊은 복사가 되지 않음
왜냐하면 a[x]에는 y좌표를 가리키는 주소값만 있기 때문
같은 주소값을 복사하니 복사본을 바꾸면 원본도 바뀌는 얕은 복사 문제 발생
예시)
ㅁ(복사배열)
ㅣ
ㅁ(1차원)→ ㅁㅁㅁㅁㅁ(2차원)
ㅁ → ㅁㅁㅁㅁㅁ
만약 1차원 배열에서 메소드 이용하면 ㅁ(복사배열)은
ㅁ
ㅁ (1차원)부분과 내용이 같은 새로운 객체 만들어서 할당하니
새롭게 만든 복사 배열을 바꿔도 원본은 안바뀜
하지만 2차원 배열에서
ㅁ
ㅁ(1차원 배열)은 그저 ㅁㅁㅁㅁㅁ(2차원 배열)들의 주소값을 가리키는 용도일 뿐이기 때문에
메소드를 이용해서 복사하고 객체를 새롭게 할당해도
2차원 배열의 주소값을 그대로 복사한 것일 뿐!
복사본을 바꾸면 원본도 바뀌게 되는 것.
⭐결론:
따라서 2차원 배열을 복사하기 위해선 for문을 돌면서 직접 찍어야 함
(2중 for문 또는 System.arraycopy+for문)
- 2차 배열에서의 깊은 복사
📌 2중for문
int[][] arr = {{1,2,3},{4,5,6}};
int[][] copy = new int[arr.length][arr[0].length];
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr[i].length; j++){
copy[i][j] = arr[i][j];
}
}
copy[0][1] = 10;
-> arr [[1, 2, 3], [4, 5, 6]]
-> copy [[1, 10, 3], [4, 5, 6]]
📌 System.arraycopy + for문
int[][] arr = {{1,2,3},{4,5,6}};
int[][] copy = new int[arr.length][arr[0].length];
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr[i].length; j++){
copy[i][j] = arr[i][j];
}
}
copy[0][1] = 10;
-> arr [[1, 2, 3], [4, 5, 6]]
-> copy [[1, 10, 3], [4, 5, 6]]