1. 배열 복사
1-1. 얕은 복사 : 배열의 주소만을 복사
: 객체의 주소값만 가져와 참조형 변수에 저장하고 하나의 객체를 두 변수가 참조하는 것
int[] origin = new int[4];
int[] copy = origin; //origin의 주소값이 copy로 대입
▶ heap영역에 객체 하나만 저장됨 → 주소값 같음
▶ origin, copy 모두 배열에 동일하게 접근 가능
int[] originArr = {1,2,3,4,5};
int[] copyArr = new int[10];
copyArr = originArr; //originArr의 주소값이 copyArr로 대입
//같은 객체를 참조하는 것으로 바뀌어 copyArr은 길이 5
System.out.println("===== 변경 전 =====");
System.out.println(Arrays.toString(originArr)); //[ 1,2,3,4,5]
System.out.println(Arrays.toString(copyArr)); //[ 1,2,3,4,5]
originArr[2] = 100;
System.out.println("===== 변경 후 =====");
System.out.println(Arrays.toString(originArr)); //[ 1,2,100,4,5]
System.out.println(Arrays.toString(copyArr)); //[ 1,2,100,4,5]
System.out.println("===== 주소 값 =====");
System.out.println(originArr); //[I@7637f22
System.out.println(copyArr); //[I@7637f22 --> 같은 객체 참조
▶ 배열의 길이가 10인 copyArr은 originArr배열과같은 객체를 참조하는 것으로 바뀌어 배열의 길이는 5가 된다.
▶ copyArr의 값 = originArr의 값
▶ copyArr의 길이 = originArr의 길이
▶ copyArr의 주소 = originArr의 주소
▶ origin과 copy는 같은 주소값을 가지고 같은 곳을 참조하기 때문에 copy(origin)에서 수정하면 origin(copy)에서도 변경된 것으로 나옴
※ System.out.println(배열이름) → 배열 주소 값
※ System.out.println(배열이름.hashCode) → 배열 주소 값 (10진수로)
※ Arrays.toString(배열이름) → 배열 전체 값 제공 / import해줘야 함
2-2. 깊은 복사 : 동일한 배열을 하나더 생성해서 실제 내부 값 복사
: 새로운 배열 객체를 생성(주소값 다름)하여 기존 배열의 데이터를 복사하는 것
* 방법1 : System.arraycopy(src, srcPos, dest, destPos, length);
System.arraycopy(src, srcPos, dest, destPos, length);
/*src : 원본 배열
*srcPos : 원본 배열의 복사할 시작점
*dest : 카피 배열
*destPos : 카피 배열의 붙여넣기 시작점
*length : 원본 배열에서 가져올 길이
*/
** 예시
int[] origin = {1,2,3,4,5};
int[] copy = new int[10]; //new로 새로 생성 -> 주소값 다름
System.arraycopy(origin, 0, copy, 2, origin.length);
//origin배열의 0번 인덱스부터 마지막에 넣은 길이(origin.length)만큼
//copy배열의 2번 인덱스부터 채우겠다는 의미
originArr -> 1 2 3 4 5
copyArr -> 0 0 1 2 3 4 5 0 0 0
▶ heap영역에 새로운 객체 저장됨 → 주소값 다름
▶ copyArr은 originArr배열과 다른 새로운 객체를 참조하기 때문에 값과 길이, 주소값 모두 다르다.
▶ copyArr의 값 != originArr의 값
▶ copyArr의 길이 != originArr의 길이
▶ copyArr의 주소 != originArr의 주소
* 방법2 : Arrays.copyOf(original, newLength)
Arrays.copyOf(original, newLength);
//original : 원본 배열
//newLength : 복사할 길이
//무조건 원본 배열의 0부터 시작
//값을 대입시켜야 함
int[] originArr = {1,2,3,4,5};
copyArr = Arrays.copyOf(originArr, 4);
copyArr2 = Arrays.copyOf(originArr, 7);
System.out.println("===== 변경 전 =====");
System.out.println(Arrays.toString(originArr)); //[1, 2, 3, 4, 5]
System.out.println(Arrays.toString(copyArr)); //[1, 2, 3, 4]
System.out.println(Arrays.toString(copyArr2)); //[1, 2, 3, 4, 5, 0, 0]
originArr[2] = 100;
System.out.println("===== 변경 후 =====");
System.out.println(Arrays.toString(originArr)); //[1, 2, 100, 4, 5]
System.out.println(Arrays.toString(copyArr)); //[1, 2, 3, 4, 5]
System.out.println("===== 주소 값 =====");
System.out.println(originArr); //[I@7637f22
System.out.println(copyArr); //[I@4926097b
1) Arrays.copyOf( originArr, 7 )
→ 원본보다 길면 자동으로 0으로 초기화되어 들어간다.
→ [1, 2, 3, 4, 5, 0, 0]
▶ Arrays.copyOf : copyArr은 OriginArr을 복사하여 새롭게 생긴 객체를 참조하게 되었으므로 길이 5가 된다.
▶ copyArr의 값 != originArr의 값
▶ copyArr의 길이 != originArr의 길이
▶ copyArr의 주소 != originArr의 주소
*방법3 : for문 이용 → 주소값 다름
int[] originArr = {1,2,3,4,5};
//for문 이용
int[] copyArr = new int[10];
for(int i=0; i<originArr.length; i++) {
copyArr[i] = originArr[i];
}
System.out.println("===== 변경 전 =====");
System.out.println(Arrays.toString(originArr)); //[1, 2, 3, 4, 5]
System.out.println(Arrays.toString(copyArr)); //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
originArr[2] = 100;
System.out.println("===== 변경 후 =====");
System.out.println(Arrays.toString(originArr)); //[1, 2, 100, 4, 5]
System.out.println(Arrays.toString(copyArr)); //[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
System.out.println("===== 주소 값 =====");
System.out.println(originArr); //[I@7637f22
System.out.println(copyArr); //[I@4926097b
▶ copyArr은 originArr배열과 다른 새로운 객체를 참조하기 때문에 값과 길이, 주소값 모두 다르다.
▶ copyArr의 값 != originArr의 값
▶ copyArr의 길이 != originArr의 길이
▶ copyArr의 주소 != originArr의 주소
*방법4 : clone()메소드 이용 -> 시작인덱스 지정 안됨, 원본 배열을 통채로 복사해서 새로운 배열 할당
int[] origin = {1,2,3,4,5};
int[] copy = origin.clone();
System.out.prinln("origin주소값 : " + origin.hashCode()); //origin주소값 : 1702146597
System.out.prinln("copy주소값 : " + copy.hashCode()); //copy주소값 : 644460953
'Java > 정리' 카테고리의 다른 글
[Java] 객체 (0) | 2021.05.14 |
---|---|
[Java] 2차원 배열 문제 (0) | 2021.05.12 |
[Java] Math.random() (0) | 2021.05.08 |
[Java] 2차원 배열 & 가변배열 (0) | 2021.05.06 |
[Java] 배열 (0) | 2021.05.05 |