아메리카노가 그렇게 맛있답니다 여러분

이번에 ICPC 문제를 풀던 도중에 알고리즘은 맞는데 계속 값이 이상하게 나오는 경우가 발생했다. 연습이었기에 다행이지, 실전이었다면 아마 순위 끝 줄 언저리에 서있지 않았을까 싶은 문제였다. 문제의 원인은 Date 객체를 LinkedList에 넣는 과정에서 깊은 복사가 아닌 얕은 복사를 하는 바람에 발생했는데 얕은 복사에 대해 알아보고 해결법을 알아본다.


얕은 복사는 Swallow Copy라 불리며 C언어의 경우로 말하면 주소값을 넘겨주는 방식이다. 그렇기 때문에 LinkedList에 넘겨준 주소값에 있는 객체값을 변경하면 LinkedList에 있는 값들이 일괄 변경되는 바람에 DFS를 구현하지 못했다.


public class Test {
  public static void main(String[] args) {
    Nod a = new Nod(new Date(1));
    Nod b = new Nod(a);
    a.day.setTime(2);
    System.out.println(b.day.getTime());
  }
}
class Nod {
  public Date day;
  public Nod(Date a) {
    day = a;
  }
  public Nod(Nod a) {
    day = a.day;
  }
}

이 코드를 돌려본다면 분명히 b의 값은 바꾼 것도 없는데 1이 아닌 2로 변경되어 있을 것이다.

이는 b가 a를 얕은 복사하였기 때문이며 깊은 복사를 하고 싶다면 new를 사용하여 새로운 객체를 만들고 값만 대입시키는 방법을 택해야 한다.


public class Test {
  public static void main(String[] args) {
    Nod a = new Nod(new Date(1));
    Nod b = new Nod(a);
    a.day.setTime(2);
    System.out.println(b.day.getTime());
  }
}
class Nod {
  public Date day;
  public Nod(Date a) {
    day = a;
  }
  public Nod(Nod a) {
    day = new Date(a.day.getTime());
  }
}

위와 같이 변경하면 깊은 복사가 일어나기 때문에 1로 올바르게 출력된다.