☕Java 객체 배열의 깊은 복사, 얕은 복사, 향상된 for문

hamsang·2022년 5월 26일
0

Java

목록 보기
13/36
post-thumbnail

☕ 객체 배열 사용하기

객체 배열은 참조 자료형으로 선언해 사용할 수 있습니다.

💻 Book 클래스

package array;

public class Book {

	private String Bookname;
	private String Author;
	
	public Book() {} //디폴트 생성자
	
	public Book(String bookname, String author) {
		this.Bookname = bookname;
		this.Author = author;
	}
	
	public void showBookInfo() {
		System.out.println(Bookname + "," + Author);
	}
}

💻 BookArray main 클래스

각 배열 요소에 인스턴스를 생성하는 코드

package array;

public class BookArray {
	public static void main(String[] args) {
		
		Book[] library = new Book[4];
		
		library[0] = new Book("태백산맥", "조정래");
		library[1] = new Book("무진기행", "김승옥");
		library[2] = new Book("데미안", "헤르만 헤세");
		library[3] = new Book("변신", "프란츠 카프카");
		
		for(int i = 0; i<library.length; i++) {
			library[i].showBookInfo();
		}
		
	}
}


☕ 배열 복사하기, System.arraycopy() 메서드

배열을 복사하는 경우는 크게 두 가지로 나뉩니다

첫째, 기존 배열과 자료형 및 크기가 똑같은 배열을 새로 만들 때
둘째, 배열의 모든 요소에 자료가 꽉 차서 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때

📌 System.arraycopy() 메서드

System.arraycopy(src, srcPos, dest, destPos, length)

각 매개변수의 의미는 다음과 같다.

매개변수의미
src복사할 배열 이름
srcPos복사할 배열의 첫 번째 위치
dest복사해서 붙여 넣을 대상 배열 이름
destPos복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치
lengthsrc에서 dest로 자료를 복사할 요소 개수

📂 예제코드

package array;

public class ArraCopy {
	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); //araycopy() 메서드
		
		for(int i = 0; i<array2.length; i++) {
			System.out.println(array2[i]);
		}
		
	}
}

array1 배열에서 array2 배열로 요소 값을 복사하는 코드입니다.
이때 복사할 대상 배열의 전체 길이가 복사할 요소 개수보다 작다면 오류가 나게 됩니다.


☕ 객체 배열의 깊은 복사, 얕은 복사

배열의 깊은 복사와 얕은 복사는 배열의 요소 값 변경시 영향을 미치게 됩니다.

📌 얕은 복사 (shallow copy)

복사된 배열이나 원본 배열이 변경될 때 두 배열의 값 모두 함께 변경된다. (변경 사항이 생겨도 항상 같은 값을 가지게 된다.)

📂 예제코드

package array;

public interface ArrayCopy2 {
	public static void main(String[] args) {
    
    	...
        
		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();
		}
}
}

bookArray1 배열의 0번째 요소를 변경했는데, bookArray2 배열까지 함께 변경됐다. 왜일까?

객체 배열 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소 값이기 때문이다. 결국 두 배열의 다른 요소가 같은 인스턴스를 가리키고 있기 때문에 복사되는 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받는다.

이와 같은 복사를 주소 값만 복사한다고 해서 '얕은 복사'라고 한다.

🤩 그렇다면 두 배열의 각 요소가 서로 다른 인스턴스를 가리켜 하나의 배열이 변경돼도 서로에게 영향을 미치지 않게 하려면 어떻게 해야할까?

📌 깊은 복사 (deep 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("박완서");
		
		
	}

}

깊은 복사를 할 경우 bookArray1 배열의 값을 바꿔도 bookArray2 배열에 영향을 미치지 않는다는 사실을 알 수 있습니다.


☕ 함께 사용하면 편한 향상된 for문!

📌 자바 5부터 제공되는 향상된 for문 (enhanced for loop)입니다.

for(변수:배열) {
	반복 실행문;
}

배열의 처음에서 끝까지 모든 요소를 참조할 때 사용하면 편리한 반복문입니다.

향상된 for문은 배열 요소 값을 순서대로 하나씩 가져와서 변수에 대입합니다. 따로 초기화와 종료 조건이 없기 때문에 배열의 시작 요소부터 끝 요소까지 실행하게 됩니다!

📂 예제코드

package array;

public class EnhancedForLoop {
	public static void main(String[] args) {
		String[] strArray = {"Java", "C", "JavaScript", "Go", "Kotlin"};
		
		for(String lang:strArray) {
			System.out.println(lang);
		}
	}
}

String형으로 선언된 strArray 배열에 문자열 5개를 저장하고,
향상된 for문을 사용해 String형 lang 변수에 strArray 배열 요소의 값을 순서대로 가져와 대입해 출력한 코드입니다!

profile
햄생

0개의 댓글

관련 채용 정보