본문 바로가기

Java

2차원 배열의 깊은 복사, 임의의 클래스 복사

1차원 배열을 복사할 땐 2가지 방법이 있다.

 

"="를 쓰는 방법과

Arrays.clone을 방법이다.

1차원 배열을 얕은 복사하기 위해선 '='를 쓰면 된다.
b = a ; 했을 경우
같은 주솟값의 객체를 고 있기 때문에
a의 값이 변경되면 b의 값도 변경된다.

1차원 배열을 깊은 복사하기 위해선 clone메소드를 쓰면 된다.
b = a.clone(); 했을 경우
a의 객체를 복사한 새로운 객체를 만들고 b가 가리키기 때문에
a의 값이 변경되어도 b의값은 바뀌지 않는다.

하지만 2차원 배열에도 clone메소드를 쓰면 깊은 복사가 되지 않는다.
이유는 간단하다.  

 

 

그림을 보면 1 -> 2 -> 3 순으로 객체를 가리키고 있다.
1차원 배열에서는 1 -> 2 가 끝이다.
2와 내용은 같지만 주솟값이 다른 새로운 객체를 만들어서 할당하면
1차원 배열에서는 2에서 내용을 담고 있기 때문에 a에서 2에 담긴 내용을 바꿔도 영향을 받지 않는 것이었다.

하지만 2차원 배열에서는 3에 내용을 담고 있다.
2는 그저 3을 가리키는 용도일 뿐이라고 생각하자.
clone메소드는 1차원 배열과 마찬가지로 2차원 배열에서도 2에 해당하는 객체를 
복사해서 새롭게 할당하므로 2차원 배열에서 2에 담긴 내용, 즉 3을 가리키는 주솟값을 그대로 복사한다.
때문에 a배열에서 값을 바꾼다면 b배열에서도 똑같이 바뀌게 된다.

 

때문에 2차원 배열을 깊은 복사할 때는 이런식으로 하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public static void main(String[] args){
        int [][] original = new int[5][5];
        int [][] copy = new int[5][5];
        int cnt = 0;
 
        for(int[] temp : original){
            copy[cnt++= temp.clone(); 
        }
 
        //또는
 
        for(int i=0; i<original.length; i++){
            copy[i] = original[i].clone();
        }
    }
 

 

또한 사용자가 만든 임의의 클래스를 서로 복사하기 위해서는
Cloneable인터페이스를 구현하여 작성하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main { 
    public static void main(String[] args){ 
        copy a = new copy("홍길동");
        copy b = (copy) a.clone(); 
    } 
class copy implements Cloneable{ 
    String name; copy(String name){
        this.name = name; 
    } 
    public Object clone(){
        Object obj = null;
        try
            obj = super.clone();
        }catch(Exception e){
        } 
        return obj;
    } 
}