깊은복사는 값 자체를 가져다 사용
얇은 복사는 주소를 가져다 사용
1.얕은 복사(shallow copy)
주소값 동일 (같은 주소값 참조)
값 자체 동일
int[] arr1 = new int[3];
int[] arr2 = arr1;
new 연산자가 공간 생성 & 주소값 생성하고,
heap의 주소값이 대입연산자 때문에 주소값0x100이 stack의 변수로 들어가게 됨
arr1의 값은? 0x100
대입연산자에 의해서 arr1에도 0x100이 들어가 있음
arr2 = arr1;에 의해 arr2에도 arr1과 같이 0x100의 주소값이 들어감
즉, 같은 주소값을 참조하는 것이며 같은 주소값을 참조하기에 둘이 같이 값을 공유한다
arr1[0] = 10;
System.out.println(arr1[0]); // 10
System.out.println(arr2[0]); // 10
아래처럼 그림으로보면 같은 곳을 화사룦가 가리키고 있다
public void method01() {
// 1.얕은 카피(shallow copy)
int[] originArr = {1,2,3,4,5};
int[] copyArr = originArr;
System.out.println(originArr); // 결과값 : [I@74a14482
System.out.println(copyArr); // 결과값 : [I@74a14482
System.out.println();
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
System.out.println();
// 원본 배열값 변경
originArr[0] = 99;
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" "); // 99 2 3 4 5
}
System.out.println();
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i]+" "); // 99 2 3 4 5
}
System.out.println();
// 변경된 값이 똑같이 반영
}
2.깊은 복사(deep copy)
새로운 배열을 만들어 기존 데이터를 모두 복사해오는 것
새로 만들어 복사하기에 원본과 복사본의 주소값이 다르고, 원본값이 변해도 복사본에 영향x
deep copy 3가지 방법
A. for문 이용
B. System.arraycopy()
C. Arrays.copyof()
A. for문 이용
public void method02() {
// 2.깊은 카피(deep copy)
// 1) for문 이용
int[] originArr = {1,2,3,4,5};
int[] copyArr = new int[5];
System.out.println(originArr); // 결과값 : [I@74a14482
System.out.println(copyArr); // 결과값 : [I@33909752
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" ");
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" ");
}
System.out.println();
System.out.println();
for(int i=0; i<originArr.length; i++) {
copyArr[i] = originArr[i];
}
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" ");
}
System.out.println();
//
originArr[0] = 99;
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" ");
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" ");
}
System.out.println();
System.out.println();
}
B. System.arraycopy()
배열길이 자동 수정 X
복사된 값의 나머지 공간은 해당 배열의 데이터 타입의 기본값으로 채워진다
ex) int 배열값을 복사하고 나머지 공간은 0으로 채워진다
double 배열값을 복사하고 나머지 공간은 0.0 char 배열값을 복사하고 나머지 공간은 공백 String 배열값을 복사하고 나머지 공간은 null
System.arraycopy()의 형태
System.arraycopy(src, srcPos, dest, destPos, length);
// src : 원본 배열
// srcPos : 포지션. 원본배열에서 복사를 시작할 위치
// dest : 복사 배열
// destpos: 복사 배열에서 붙여놓기를 시작할 위치
// length : 얼만큼 복사를 해올지에 대한 복사 길이
public void method03() {
// 2.깊은 카피(deep copy)
// 2)System.arraycopy()
int[] originArr = {1,2,3,4,5};
int[] copyArr = new int[10];
// 원본 배열의 0(index)번째부터 원본배열 길이만큼 복사한 것을 복사 배열 3번째서부터 붙여넣기
// System.arraycopy(src, srcPos, dest, destPos, length);
System.arraycopy(originArr, 0, copyArr, 3, originArr.length);
// 인덱스 3번째부터 넣기에 앞의 셋은 000이고 오리진arr5개값 뺴고 나머지도 0으로 채워짐
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" "); // 0 0 0 1 2 3 4 5 0 0
}
C. Arrays.copyof()
Arrays.copyOf(original, newLength)
- original : 원본
- newLength : 얼마만큼 복사할지
배열 길이 자동 수정 O
배열 길이만큼 복사해오기에 System.arraycopy()처럼 공간이 남지않는다 원본 길이보다 길게 복사할 경우, 남는 공간은 원본의 데이터타입 기본값으로 채운다
public void method04() {
// 3) Arrays.copyof()
int[] originArr = {1,2,3,4,5};
int[] copyArr = new int[10];
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" ");
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" ");
}
System.out.println();
// Arrays.copyof()
// Arrays.copyOf(original, newLength)
// original : 원본
// newLength : 얼마만큼 복사할지
Arrays.copyOf(originArr, originArr.length);
// Arrays.copyOf 위에 마우스 포인터 올리고 나오는 '노란색 설명'
// int[] java.util.Arrays.copyOf(int[] original, int newLength)
// java util.Arrays
// 맨 앞에 값 int[]의 의미: 반환값 데이터타입이 무엇인지 알려줌. 즉 int[] 인트 배열을 반환함
copyArr = Arrays.copyOf(originArr, originArr.length); //copyArr에 담음
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
// 원본 배열값 변경
originArr[0] = 99;
for(int i=0; i<originArr.length; i++) {
System.out.print(originArr[i]+" "); // 99 2 3 4 5
}
System.out.println();
for(int i=0; i<copyArr.length; i++) {
System.out.print(copyArr[i]+" "); // 1 2 3 4 5
}
System.out.println();
}