본문 바로가기

컴퓨터언어/JAVA(자바)

[JAVA강좌] 29강 배열 복사하기

728x90
반응형

 

 

 

 

 

 

- 배열 복사는 기존 배열과 자료형 및 배열크기가 똑같은 배열을 새로 만들 때 사용합니다.

- 또, 배열의 모든 자료요소가 꽉 차서 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때 배열을 복사합니다.

- 이번 강좌에서는 다양한 배열 복사 방법을 보도록 하겠습니다. 

 

 

 

 

 

 

 

 

 

 

 

 

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값이 대입이 됩니다. 

 

 

 

 

 

 

 

 

 

728x90
반응형

 

 

 

 

 

 

 

 

 

 

 

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의 값을 변경했다고 바뀌지 않는 것을 확인할 수 있습니다. 

 

 

 

 

 

728x90
반응형