경험의 기록

얕은 복사란?

▶ 복사시 객체의 주소값을 복사하여 동일한 주소값을 가진다.

깊은 복사란?

▶ 복사시 객체의 데이터 자체를 복사하여 다른 주솟값을 가진다.

 

1차원 배열

public class Test{
	public static void main(String[] args) throws Exception{
		int[] arr1 = {1,2,3,4};
		
		// 얕은 복사
		int[] arr2 = arr1;
		
		// 깊은 복사
		int[] arr3 = arr1.clone();
		
		arr1[3] = 5;
		
		System.out.println("[arr1] : " + arr1 + " " + Arrays.toString(arr1));
		System.out.println("[arr2] : " + arr2 + " " + Arrays.toString(arr2));
		System.out.println("[arr3] : " + arr3 + " " + Arrays.toString(arr3));
	}	
}

자바에서 객체를 ' = ' 로 복사하게 되면 얕은 복사가 일어난다.

그래서 arr1에서 변경된 값이 복사본인 arr2에서도 변경되어 있는 것을 확인할 수 있고, 동일한 주솟값을 가지는 것을 확인할 수 있다.

 

배열의 clone() 메서드를 사용하면

객체의 데이터 자체를 복사하여 새로 생성하기 때문에 원래의 값이 출력되고 다른 주솟값을 가지는 것을 확인할 수 있다.

 

하지만, 2차원 배열의 경우는 다르다.

 

2차원 배열

public class Test{
	public static void main(String[] args) throws Exception{
		int[][] arr1 = {{1,2},{3,4},{5,6}};
		
		// 얕은 복사
		int[][] arr2 = arr1;
		int[][] arr3 = arr1.clone();
		
		arr1[2][0] = 10;
		
		for(int i = 0; i < arr1.length; i++) {
			System.out.print(Arrays.toString(arr1[i]) + " ");
		}
		System.out.println();
		
		for(int i = 0; i < arr2.length; i++) {
			System.out.print(Arrays.toString(arr2[i]) + " ");
		}
		System.out.println();
		
		for(int i = 0; i < arr3.length; i++) {
			System.out.print(Arrays.toString(arr3[i]) + " ");
		}
	}	
}

2차원 배열의 경우, 위 결과처럼 clone을 했음에도 불구하고 변경된 값이 전부 적용 되버리는 것을 알 수 있다.

 

왜냐하면 객체들을 담고 있는 주소의 주솟값데이터를 새로 생성해 복사한 것이기 때문이다.

따라서 깊은 복사를 하려면 반복문으로 객체를 각각 복사해주어야 한다.

 

public class Test{
	public static void main(String[] args) throws Exception{
		int[][] arr1 = {{1,2},{3,4},{5,6}};
		
		// 얕은 복사
		int[][] arr2 = arr1;
		
		int[][] arr3 = new int[3][2];
		int[][] arr4 = new int[3][2];
		
		// 깊은 복사 (for문 + clone 사용)
		for(int i = 0; i < arr1.length; i++) {
			arr3[i] = arr1[i].clone();
		}
			
		// 깊은 복사 (2중 for문 사용)
		for(int i = 0; i < arr1.length; i++) {
			for(int j = 0; j < 2; j++) {
				arr4[i][j] = arr1[i][j];
			}
		}
		
		
		arr1[2][0] = 10;
		
		for(int i = 0; i < arr1.length; i++) {
			System.out.print(Arrays.toString(arr1[i]) + " ");
		}
		System.out.println();
		
		for(int i = 0; i < arr2.length; i++) {
			System.out.print(Arrays.toString(arr2[i]) + " ");
		}
		System.out.println();
		
		for(int i = 0; i < arr3.length; i++) {
			System.out.print(Arrays.toString(arr3[i]) + " ");
		}
		System.out.println();
		
		for(int i = 0; i < arr4.length; i++) {
			System.out.print(Arrays.toString(arr4[i]) + " ");
		}
	}	
}

이중 포문으로 반복하거나

2차원 배열의 한 행마다 clone 해주는 방식으로 깊은 복사를 할 수 있다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading