본문 바로가기

자바 기초

자바 배열 복사, arraycopy - Do it! 자바프로그래밍기초

배열 복사는 기존 배열과 자료형 및 배열 크기가 똑같은 배열을 새로 만들거나 배열의 모든 요소에 자료가 꽉차서 더 큰 배열을 만들어줄 때 사용한다.

배열을 복사하는 방법은 두 가지가 있다.

1. 기존 배열과 배열 길이가 같거나 더 긴 배열을 만들고 for문을 사용하여 각 요소 값을 반복해서 복사하는 방법

2. System.arraycopy(src, srcPos, dest, destPos, length) 메서드를 사용하는 방법이다.

src : 복사할 배열 이름

srcPos : 복사할 배열의 첫번째 위치

dest : 복사해서 붙여 넣을 대상 배열 이름

destPos : 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치

length : src 에서 dest로 자료를 복사할 요소 개수

 

package array;

public class ArrayCopy {

	public static void main(String[] args) {
		int[] array1 = {10, 20, 30, 40, 50};
		int[] array2 = {1,2,3,4,5};
		
		System.arraycopy(array1, 0, array2, 1, 4);
		//                 복사할 배열, 복사할 첫 위치, 대상 배열, 붙여 넣을 첫 위치, 복사할 요소 개수
		for (int i = 0; i < array2.length ; i++)
		{
			System.out.println(array2[i]);
		}
	}

}

위 코드에서는 요소 4개를 복사했지만, 만약에 5개를 복사한다면 array2 배열 길이보다 요소 개수가 많아지므로 오류가 발생한다.

 

 

 

 

 

 

package array;

public class ObjectCopy2 {

	public static void main(String[] args) {
		
		Book[] bookArray1 = new Book[3];
		Book[] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥", "조정래");
		bookArray1[1] = new Book("데미안", "헤르만 헤세");
		bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
		
		System.arraycopy(bookArray1, 0, bookArray2, 0, 3);
		
		for(int i = 0; i < bookArray2.length ; i++)
		{
			bookArray2[i].showBookInfo();
		}
		
		
		System.out.println("=== bookArray1 ===");
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		for(int i = 0; i < bookArray1.length; i++)
		{
			bookArray1[i].showBookInfo();
		}
		
		
		System.out.println("=== bookArray2 ===");
		for(int i = 0; i < bookArray2.length; i++)
		{
			bookArray2[i].showBookInfo();
		} 
	}

}

위 코드는 객체 배열을 복사한 것이다. 객체 배열도 마찬가지로 복사해서 사용할 수 있는데,

객체 배열을 사용하려면 꼭 인스턴스를 생성해서 넣어야 한다고 했는데, 이 경우는 어떻게 된 것일까?

출력화면을 보면 bookArray1의 변경사항이 bookArray2에도 반영되었다. 객체 배열의 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소값이기 때문이다. 

즉 객체 배열을 복사할 때 인스턴스를 따로 생성하는 것이 아니고 기존 인스턴스의 주소값만 복사한다.

결국 두 배열의 서로 다른 요소가 같은 인스턴스를 가리키고 있으므로 복사되는 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받는 것이다.

위와 같은 복사를 주소값만 복사한다고 해서 '얕은 복사(shallow copy)'라고 한다.

 

 

package array;

public class ObjectCopy3 {

	public static void main(String[] args) {
		
		Book[] bookArray1 = new Book[3];
		Book[] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥", "조정래");
		bookArray1[1] = new Book("데미안", "헤르만 헤세");
		bookArray1[2] = new Book("어떻게 살 것인가", "유시민");
		
		bookArray2[0] = new Book();
		bookArray2[1] = new Book();
		bookArray2[2] = new Book();
		
		for (int i = 0; i < bookArray1.length ; i++)
		{
			bookArray2[i].setBookName(bookArray1[i].getBookName());
			bookArray2[i].setAuthor(bookArray1[i].getAuthor());
		}
		
		for(int i = 0; i < bookArray2.length; i++)
		{
			bookArray2[i].showBookInfo();
		}
		
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		System.out.println("=== bookArray1 ===");
		for (int i = 0; i < bookArray1.length; i++)
		{
			bookArray1[i].showBookInfo();
		}
		
		System.out.println("=== bookArray2 ===");
		for(int i =0 ; i < bookArray2.length; i++)
		{
			bookArray2[i].showBookInfo();
		}
		
		// 이렇게 인스턴스를 따로 관리하고 싶다면 인스턴스를 만들고 그 값을 복사해야한다. 이를 '깊은 복사' 라고 함.
	}

}

위 코드는 복사할 배열에 인스턴스를 따로 생성한 후 요소 값을 복사한다. 이렇게 하면 복사할 배열 요소는 기존 배열 요소와 서로 다른 인스턴스를 가리키므로 기존 배열의 요소 값이 변경되어도 영향을 받지 않는다.

이렇게 인스턴스를 따로 관리허기 위해 직접 인스턴스를 만들고 그 값을 복사하는 것을 '깊은 복사(deep copy)'라고 한다.