안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
배열의 복사는 크게 얕은 복사와 깊은 복사로 나뉘어집니다.
배열의 복사에 대해서 알아보겠습니다.
☞ 얕은 복사 (shallow copy)
- 객체 주소값을 복사 (스택 영역의 값 복사)
- 같은 객체를 공유
public void test1() {
char[] arr1 = new char[] {'a', 'b', 'c'};
char[] arr2 = arr1; //참조주소값 복사(스택메모리)
for(int i = 0; i < arr1.length; i++) {
System.out.println("arr1 : " + arr1[i] + " / arr2 : " + arr2[i]);
}
System.out.println("arr1 : " + arr1.hashCode() + " , arr2 : " + arr2.hashCode());
}
@콘솔출력값
arr1 : a / arr2 : a
arr1 : b / arr2 : b
arr1 : c / arr2 : c
arr1 : 1227229563 , arr2 : 1227229563
arr2에 arr1을 대입(복사) 하고 각 인덱스 별 값과 해쉬코드를 출력해보았습니다.
스택 메모리의 주소값을 그대로 가져와 복사했기 때문에 같은 객체를 공유하게 됩니다.
같은 객체를 공유하기 때문에 하나의 값을 바꾸면 값이 모두 변경됩니다.
arr1[1] = 'f';
for(int i = 0; i < arr1.length; i++) {
System.out.println("arr1 : " + arr1[i] + " / arr2 : " + arr2[i]);
}
@콘솔출력값
arr1 : a / arr2 : a
arr1 : f / arr2 : f
arr1 : c / arr2 : c
arr1[1]만 'f'로 변경했는데 arr2[1]도 동일하게 'f'로 변경된 것을 볼 수 있습니다.
☞ 깊은 복사 (deep copy)
- 배열 객체를 복사 (힙 영역을 복사)
- 동일한 값을 가진 배열 객체가 2개가 되는 것
① 직접 값 대입하여 복사
public void test2() {
int[] arr1 = new int[] {10, 20, 30};
int[] arr2 = new int[arr1.length];
for(int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i]; //값 복사
}
//값 출력
for(int i = 0; i < arr1.length; i++) {
System.out.println("arr1 : " + arr1[i] + " / arr2 : " + arr2[i]);
}
System.out.println("arr1 : " + arr1.hashCode() + " , arr2 : " + arr2.hashCode());
}
@콘솔출력값
arr1 : 10 / arr2 : 10
arr1 : 20 / arr2 : 20
arr1 : 30 / arr2 : 30
arr1 : 1227229563 , arr2 : 1982791261
arr2라는 객체 생성 후 직접 값을 대입하여 복사하였습니다.
동일한 값을 갖고 있지만, 이 둘은 서로 다른 객체를 공유하고 있으므로 해쉬코드 값이 상이합니다.
서로 다른 객체와 주소값을 갖고 있으므로 하나의 값을 변경해도 복사한 객체에는 아무런 변화가 없습니다.
arr1[1] = 50;
for(int i = 0; i < arr1.length; i++) {
System.out.println("arr1 : " + arr1[i] + " / arr2 : " + arr2[i]);
}
@콘솔출력값
arr1 : 10 / arr2 : 10
arr1 : 50 / arr2 : 20
arr1 : 30 / arr2 : 30
원본 arr1[1]을 50으로 변경해도 복사한 arr2[1]의 값은 그대로 인 것을 볼 수 있습니다.
② System.arraycopy (static 메소드 → 객체 생성 X)
public void test3() {
double[] dArr1 = new double[] {3.3, 5.0, 2.6};
double[] dArr2 = new double[dArr1.length];
//void java.lang.System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//darr1의 0번째부터 darr1.length길이만큼 darr2의 0번째부터 복사하여 대입해줘~
System.arraycopy(dArr1, 0, dArr2, 0, dArr1.length);
for(int i = 0; i < dArr1.length; i++) {
System.out.println("dArr1 : " + dArr1[i] + " / dArr2 : " + dArr2[i]);
}
System.out.println("dArr1 : " + dArr1.hashCode() + " , dArr2 : " + dArr2.hashCode());
}
@콘솔출력값
dArr1 : 3.3 / dArr2 : 3.3
dArr1 : 5.0 / dArr2 : 5.0
dArr1 : 2.6 / dArr2 : 2.6
dArr1 : 2104457164 , dArr2 : 1521118594
java.lang 패키지(임포트 x) 의 System 클래스의 arraycopy 메소드를 사용하여 값을 복사하였습니다.
마찬가지로 배열 객체를 복사한 것이므로 서로 다른 객체를 가르키고 있으며, 해쉬코드도 상이합니다.
원하는 만큼 복사해오기엔 제일 좋은 방법이겠네요!
dArr1[1] = 15.3;
for(int i = 0; i < dArr1.length; i++) {
System.out.println("dArr1 : " + dArr1[i] + " / dArr2 : " + dArr2[i]);
}
@콘솔출력값
dArr1 : 3.3 / dArr2 : 3.3
dArr1 : 15.3 / dArr2 : 5.0
dArr1 : 2.6 / dArr2 : 2.6
따라서 원본 dArr1[1]의 값을 변경해도 복사본인 dArr2[1]의 값에는 변함이 없습니다.
③ clone
public void test4() {
boolean[] bArr1 = new boolean[] {true, false, true};
boolean[] bArr2 = bArr1.clone();
for(int i = 0; i < bArr1.length; i++) {
System.out.println("bArr1 : " + bArr1[i] + " / bArr2 : " + bArr2[i]);
}
System.out.println("bArr1 : " + bArr1.hashCode() + " , bArr2 : " + bArr2.hashCode());
}
@콘솔출력값
bArr1 : true / bArr2 : true
bArr1 : false / bArr2 : false
bArr1 : true / bArr2 : true
bArr1 : 1227229563 , bArr2 : 1982791261
clone메소드를 사용하여 bArr1 배열 객체를 복사해왔으며, 마찬가지로 서로 다른 객체를 가리키며 해쉬코드는 상이합니다.
깊은 복사 중 제일 간단한 방법이네요!
bArr1[1] = true;
for(int i = 0; i < bArr1.length; i++) {
System.out.println("bArr1 : " + bArr1[i] + " / bArr2 : " + bArr2[i]);
}
@콘솔출력값
bArr1 : true / bArr2 : true
bArr1 : true / bArr2 : false
bArr1 : true / bArr2 : true
따라서 원본 bArr1[1]의 값을 변경해도 복사본인 bArr2[1]의 값에는 변함이 없습니다.
'Java > Java' 카테고리의 다른 글
2차원 배열) 2차원 배열이란?, 생성 방법 (0) | 2022.03.09 |
---|---|
반복문) 중첩 반복문, 이중for문, 레이블 (0) | 2022.03.09 |
배열) 배열이란?, 배열의 특징, 객체의 특징, for-each문 (0) | 2022.03.08 |
제어 키워드) break, continue 제어 키워드 (0) | 2022.03.08 |
반복문) while문, do-while문, while문 무한루프 (0) | 2022.03.07 |