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

     

     

    얕은 복사

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

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

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

     

    깊은 복사

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

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

     


     

     

    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

     

     

     

    댓글