Java

[ Java ] 1차원, 2차원 배열 복사 - 깊은 복사와 얕은 복사

yebeen 2024. 2. 8. 00:52

 

 

얕은 복사

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

- 즉 원래 배열의 주솟값을 가져오는 것

- 같은 곳을 가리키기 때문에 한쪽에서 데이터를 변경하면 다른 한쪽도 변경된 데이터에 접근할 수 있다.

 

깊은 복사

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

- 즉 원래 배열을 그대로 가져오는 것

 


 

 

1차원 배열 복사

 

1. ' = ' 사용 [ 얕은 복사 ]

자바에서 객체를 ' = ' 을 통해 복사하게 되면 얕은 복사가 일어나 두 객체가 같은 곳을 바라보게 된다.

 

 

2. clone() 함수 사용 [ 깊은 복사 ]

만약 같은 공간을 가리키는 것이 아니라
배열의 값 자체를 복사하여 새로운 공간에 할당하고 주소를 받고 싶다면 배열의 clone() 함수를 사용하면 된다.

 

 

아래 코드를 돌려보면 arr1과 arr2는 같은 주소값을 가지지만

arr1과 arr3의 주소값은 다른 것을 확인할 수 있다.

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));
	}	
}

 

 

 


 

 

2차원 배열 복사

 

1. ' = ' , arr2  = arr1.clone() [ 얕은 복사 ]

그렇다면 2차원 배열도 1차원 배열처럼 복사본을 넣을 배열 = 복사할 배열. 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 = 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]) + " ");
		}
	}	
}

 

 

그 이유는 객체를 복사한 것이 아닌 객체들을 담고 있는 주소의 주솟값 데이터들을 복사하였기 때문이다.

즉 1,2,4,7,8과 같은 데이터를 복사한 것이 아닌 이 데이터를 담고 있는 주소의 값을 가지고  있는 것이다.

 

 

 

2. 2중 for문 or 1중포문+[ clone() or System.arraycopy() ] [ 깊은 복사 ]

따라서 깊은 복사를 하기 위해서는 반복문을 사용해 객체를 각각 복사해야 한다.

 

2-1) 2중 for문

// 깊은 복사 (for문 + clone 사용)
for(int i = 0; i < arr1.length; i++) {
	arr2[i] = arr1[i].clone();
}

 

 

2-2) 1중 for문 + clone()

// 깊은 복사 (2중 for문 사용)
for(int i = 0; i < arr1.length; i++) {
	for(int j = 0; j < 2; j++) {
		arr3[i][j] = arr1[i][j];
	}
}

 

 

2-3) 1중 for문 + System.arraycopy(원래배열, 복사 시작 index, 새로운배열, 시작 index, 복사할 길이)

int[][] arr2 = new int[arr1.length][arr1[0].length];

for(int i = 0; i < arr1.length; i++){
	System.arraycopy(arr1[i], 0, arr2[i], 0, arr1[i].length);
}

 

 

 


 

 

참고문헌

https://hanyeop.tistory.com/366

https://dev-note-97.tistory.com/36