- 배열 복사는 기존 배열과 자료형 및 배열크기가 똑같은 배열을 새로 만들 때 사용합니다.
- 또, 배열의 모든 자료요소가 꽉 차서 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때 배열을 복사합니다.
- 이번 강좌에서는 다양한 배열 복사 방법을 보도록 하겠습니다.
1. 일반 배열 복제
- 이번에는 객체 배열이 아닌 일반 배열 복제하는 것을 보도록 하겠습니다.
1) 단순 대입
- 먼저 배열을 단순하게 대입하는 것을 해보겠습니다.
- 대입연산자를 이용한 배열 복사는 되지 않습니다.
- 안된다는 것을 보여드리기 위해 해보겠습니다.
- 패키지와 클래스 파일을 생성해줍니다.
## 배열 대입 코드 - Ex08_ArrayCopy.java
package ch18_array;
public class Ex08_ArrayCopy {
public static void main(String[] args) {
//배열 선언
int[] nums01 = new int[] {1,2,3};
//nums02에 nums01을 대입
int[] nums02 = nums01;
//같은 주소를 참조하기 때문에 nums01값을 복사한 것이 아닌 참조
System.out.println(nums01);
System.out.println(nums02);
//nums02의 인덱스2번의 값을 5번으로 변경
nums02[2] = 5;
//주소 참조라 둘다 변경됨
System.out.println(nums01[2]);
System.out.println(nums02[2]);
}
}
- 코드에 주석으로 설명을 달아놨습니다.
- 결과적으로 대입은 복제가 아니라 주소 참조라는 점을 잘 기억해야 합니다.
## 배열 대입 결과 - Ex08_ArrayCopy.java
- nums01과 nums02는 둘다 같은 주소를 참조한다는 것을 볼 수 있습니다.
- nums02의 값만 바꿨지만, 둘다 5로 변경된 것을 확인할 수 있습니다.
2) 배열 복사 - for문 사용
- 반복을 통해서 그대로 복제를 해보도록 하겠습니다.
## 배열 for문 복제 코드 - Ex09_ArrayCopy.java
package ch18_array;
public class Ex09_ArrayCopy {
public static void main(String[] args) {
//배열 선언 및 초기화
int[] nums01 = new int[] {1,2,3};
//num01을 그대로 복제, 개수를 같게 처리
int[] nums02 = new int[nums01.length];
//nums02에 nums01의 값을 같은 인덱스 번호로 처리
for(int i=0;i<nums02.length;i++) {
nums02[i] = nums01[i];
}
//nums02의 값을 반복출력
for(int i : nums02) {
System.out.println(i);
}
}
}
- 설명은 코드에 주석으로 달아놨습니다.
## 배열 for문 복제 결과 - Ex09_ArrayCopy.java
- 그럼 복제된 값이 잘 도출되는 것을 확인할 수 있습니다.
3) System.arraycopy();
- System객체가 갖고 있는 arraycopy() 메서드를 통해 복제를 해보겠습니다.
## System.arraycopy(); 문법
System.arraycopy(복사할배열명,복사할첫위치,새로운배열명,붙여넣을위치,복사할개수);
## System.arraycopy(); 모두 복제 코드 - Ex10_ArrayCopy.java
- 첫번째로는 전부 복제하는 것을 보겠습니다.
package ch18_array;
public class Ex10_ArrayCopy {
public static void main(String[] args) {
//배열 선언 및 초기화
int[] nums01 = new int[] {1,2,3};
//num01을 그대로 복제, 개수를 같게 처리
int[] nums02 = new int[nums01.length];
//nums01의 0번부터 3개를 nums02의 0번 위치에 붙임
System.arraycopy(nums01, 0, nums02, 0, 3);
//nums02의 값을 반복출력
for(int i : nums02) {
System.out.println(i);
}
}
}
## System.arraycopy(); 모두 복제 결과 - Ex10_ArrayCopy.java
- 그럼 복제된 값이 잘 도출되는 것을 확인할 수 있습니다.
## System.arraycopy(); 일부 복제 코드 - Ex11_ArrayCopy.java
- 두번째로는 일부 복제하는 것을 보겠습니다.
package ch18_array;
public class Ex11_ArrayCopy {
public static void main(String[] args) {
//배열 선언 및 초기화
int[] nums01 = new int[] {1,2,3};
//num01을 그대로 복제, 개수를 같게 처리
int[] nums02 = new int[nums01.length];
//nums01의 1번부터 2개를 nums02의 0번 위치에 붙임
System.arraycopy(nums01, 1, nums02, 0, 2);
//nums02의 값을 반복출력
for(int i : nums02) {
System.out.println(i);
}
}
}
## System.arraycopy(); 일부 복제 결과 - Ex11_ArrayCopy.java
- 이번에는 nums01의 1번 위치부터 2개, 즉 2와 3을 복제해 와서 처음에 붙입니다.
- 그럼 마지막은 처리가 안되는데, int의 기본값인 0값이 대입이 됩니다.
2. 객체 배열 복제
- 이번에는 객체 배열을 복제하는 것을 보도록 하겠습니다.
1) 얕은 복사
- 얕은 복사는 기본 자료형 복제할 때 대입한 것처럼 주소만 복제가 되는 것을 말합니다.
- 무슨 이야기인지는 직접 보는 것이 더 좋겠죠?
- 기존에 만들어 놓은 Webtoon.java를 사용하겠습니다.
- 없는 분은 Webtoon.java코드를 아래 붙여드릴테니 생성해 주세요.
## Webtoon.java 코드
package ch18_array;
public class Webtoon {
//멤버변수 선언
private String webtoonName;
private String author;
//기본생성자 - 안적어도 됨
public Webtoon() { }
//웹툰명과 저자를 매개변수로 받는 생성자
public Webtoon(String webtoonName, String author) {
this.webtoonName = webtoonName;
this.author = author;
}
//게터/세터
public String getWebtoonName() {
return webtoonName;
}
public void setWebtoonName(String webtoonName) {
this.webtoonName = webtoonName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//출력 메서드
public void printWebtoonInfo() {
System.out.println("웹툰명 : " + webtoonName);
System.out.println("저자명 : " + author);
}
}
## 얕은 복사 코드 - WebtoonMain01.java
package ch18_array;
public class WebtoonMain01 {
public static void main(String[] args) {
//웹툰 객체 배열 선언
Webtoon[] webtoon01 = new Webtoon[3];
//인스턴스 생성
webtoon01[0] = new Webtoon("내남편과결혼해줘","LICO");
webtoon01[1] = new Webtoon("이제 곧 죽습니다","이원식/꿀찬");
webtoon01[2] = new Webtoon("연애혁명","232");
//새로운 배열
Webtoon[] webtoon02 = new Webtoon[webtoon01.length];
//배열 복사
System.arraycopy(webtoon01, 0, webtoon02, 0, 3);
//webtoon02 출력
System.out.println("==========webtoon02=========");
for(Webtoon i : webtoon02) {
i.printWebtoonInfo();
System.out.println("====================");
}
//webtoon01의 첫번째 배열 데이터 변경
webtoon01[0].setWebtoonName("마음의 소리");
webtoon01[0].setAuthor("조석");
//webtoon02 다시출력
System.out.println("==========webtoon02=========");
for(Webtoon i : webtoon02) {
i.printWebtoonInfo();
System.out.println("====================");
}
}
}
- 이번에는 인스턴스를 3개만 생성했습니다.
- webtoon01의 배열을 webtoon02 배열에 그대로 복제했습니다.
- webtoon01의 데이터를 변경 후 다시 webtoon02를 출력해 보겠습니다.
## 얕은 복사 결과 - WebtoonMain01.java
- 역시 같은 주소를 참조하기 때문에 이렇게 복사하면 webtoon01의 값이 바뀌면 webtoon02의 값도 바뀝니다.
- 이러면 문제가 좀 많을 수 있겠죠?
2) 깊은 복사
- 얕은 복사의 문제점은 위에서 확인을 했습니다.
- System.arraycopy()를 사용하면 객체 배열의 주소를 참조합니다.
- 대부분의 경우는 이렇게 복제해도 상관없지만, 완전한 새롭게 만들고 싶다면 문제가 생깁니다.
- 그래서 새로운 인스턴스를 만들고 그 값을 복제해야 합니다.
- 이것은 깊은 복사라고 합니다.
## 깊은 복사 코드 - WebtoonMain02.java
package ch18_array;
public class WebtoonMain02 {
public static void main(String[] args) {
//웹툰 객체 배열 선언
Webtoon[] webtoon01 = new Webtoon[3];
//인스턴스 생성
webtoon01[0] = new Webtoon("내남편과결혼해줘","LICO");
webtoon01[1] = new Webtoon("이제 곧 죽습니다","이원식/꿀찬");
webtoon01[2] = new Webtoon("연애혁명","232");
//새로운 배열
Webtoon[] webtoon02 = new Webtoon[webtoon01.length];
//인스턴스를 기본생성자로 처리 - 값을 복제해올 것이기 때문
webtoon02[0] = new Webtoon();
webtoon02[1] = new Webtoon();
webtoon02[2] = new Webtoon();
//값을 얻어와서 처리
for(int i=0;i<webtoon02.length;i++) {
webtoon02[i].setWebtoonName(webtoon01[i].getWebtoonName());
webtoon02[i].setAuthor(webtoon01[i].getAuthor());
}
//webtoon02 출력
System.out.println("==========webtoon02=========");
for(Webtoon i : webtoon02) {
i.printWebtoonInfo();
System.out.println("====================");
}
//webtoon01의 첫번째 배열 데이터 변경
webtoon01[0].setWebtoonName("마음의 소리");
webtoon01[0].setAuthor("조석");
//webtoon02 다시출력
System.out.println("==========webtoon02=========");
for(Webtoon i : webtoon02) {
i.printWebtoonInfo();
System.out.println("====================");
}
}
}
- 이번에는 새로운 인스턴스를 기본생성자로 처리합니다.
- 값을 미리 넣을 필요 없이 복제해 올 것이기 때문입니다.
- 반복문을 통해 값을 얻어와서 변경해 줍니다.
- 그럼 주소가 아닌 값을 직접 가져온 것이기 때문에 복제에 문제가 없습니다.
## 깊은 복사 결과 - WebtoonMain02.java
- webtoon01의 값을 변경했다고 바뀌지 않는 것을 확인할 수 있습니다.
'컴퓨터언어 > JAVA(자바)' 카테고리의 다른 글
[JAVA강좌] 31강 자바 배열 - 로또 프로그램 (1) | 2024.01.29 |
---|---|
[JAVA강좌] 30강 배열 정렬 - sort() (0) | 2024.01.26 |
[JAVA강좌] 28강 객체 배열 생성 (0) | 2024.01.26 |
[JAVA강좌] 27강 향상된 for문과 배열 (0) | 2024.01.26 |
[JAVA강좌] 26강 자바 배열 (0) | 2024.01.26 |