배열 복사는 기존 배열과 자료형 및 배열 크기가 똑같은 배열을 새로 만들거나 배열의 모든 요소에 자료가 꽉차서 더 큰 배열을 만들어줄 때 사용한다.
배열을 복사하는 방법은 두 가지가 있다.
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)'라고 한다.
'자바 기초' 카테고리의 다른 글
자바 ArrayList - Do it! 자바프로그래밍기초 (0) | 2022.07.20 |
---|---|
자바 다차원배열 - Do it! 자바프로그래밍기초 (0) | 2022.07.20 |
자바 배열, array, 객체배열 - Do it! 자바프로그래밍기초 (0) | 2022.07.20 |
자바 static 변수, 클래스 변수- Do it! 자바프로그래밍기초 (0) | 2022.07.19 |
자바 객체 간 협력 - Do it! 자바프로그래밍기초 (0) | 2022.07.19 |