본문 바로가기
Java/정리

[Java] 배열복사

by 콧등치기국수 2021. 5. 11.

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