Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags more
Archives
Today
Total
관리 메뉴

ultra_dev

배열 <깊은 복사, 얕은 복사> 본문

SPRING&JAVA

배열 <깊은 복사, 얕은 복사>

ultra_dev 2023. 1. 13. 00:37

깊은 복사(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]]

'SPRING&JAVA' 카테고리의 다른 글

View Table + JPA 매핑  (0) 2023.11.06
Schema 여정기 Multi-Tenancy(feat. PostgreSQL)  (0) 2023.11.01
체크 예외, 언체크 예외  (0) 2023.05.27
JPA 기본  (0) 2023.04.06
(pathVariable/QueryParameter)//(AccessToken,RefreshToken)  (0) 2023.01.12
Comments