티스토리 뷰

좌표미션을 진행하다 헷갈려서 노가다로 직접 값 변화를 확인해보기로 했다.

Shallow Copy vs Deep Copy

먼저 3가지의 복사 방법 비교

링크를 참조한, 얕은복사/깊은복사/더깊은복사

public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    private static void test1() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = origin;

        origin.add(new Car("sonata"));
        copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest1 : copy = origin");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test2() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = new ArrayList<>(origin);

        origin.add(new Car("sonata"));
        copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest2 : copy = new ArrayList<>(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test3() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = deepCopy(origin);

        origin.add(new Car("sonata"));
        copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest3 : copy = deepCopy(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static List<Car> deepCopy(List<Car> origin) {
        return origin.stream()
                .map(Car::clone)
                .collect(Collectors.toList());
    }


Collections.unmodifiableList

copy를 Collections.unmodifiableList로 만들었더니,
copy에 add()와 같은 추가/변경/삭제 연산을 할수없다.

public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    private static void test1() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(origin);

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest1 : copy = origin");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test2() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(new ArrayList<>(origin));

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest2 : copy = new ArrayList<>(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test3() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(deepCopy(origin));

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        origin.get(0).setName("soul");
        copy.get(1).setName("bmw");

        System.out.println("\ntest3 : copy = deepCopy(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static List<Car> deepCopy(List<Car> origin) {
        return origin.stream()
                .map(Car::clone)
                .collect(Collectors.toList());
    }


객체가 VO라면 copy(복사)의 고민이 해결된다

이때 Car 객체가 (setter 메서드가 없어 상태를 변경할수없는) 불변의 VO라면?

public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    private static void test1() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(origin);

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        //origin.get(0).setName("soul");
        //copy.get(1).setName("bmw");

        System.out.println("\ntest1 : copy = origin");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test2() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(new ArrayList<>(origin));

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        //origin.get(0).setName("soul");
        //copy.get(1).setName("bmw");

        System.out.println("\ntest2 : copy = new ArrayList<>(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static void test3() {
        List<Car> origin = new ArrayList<>();
        origin.add(new Car("k5"));
        origin.add(new Car("k9"));

        List<Car> copy = Collections.unmodifiableList(deepCopy(origin));

        origin.add(new Car("sonata"));
        //copy.add(new Car("avante"));

        //origin.get(0).setName("soul");
        //copy.get(1).setName("bmw");

        System.out.println("\ntest3 : copy = deepCopy(origin)");
        System.out.println("origin : " + origin);
        System.out.println("copy : " + copy);
    }

    private static List<Car> deepCopy(List<Car> origin) {
        return origin.stream()
                .map(Car::clone)
                .collect(Collectors.toList());
    }

더이상 객체의 상태변화에 대한 걱정을 하지않아도 된다.
리스트관리(리스트 값 추가add/변경set/삭제remove)만 잘하면 된다.
굳이 stream과 clone을 이용해 deepCopy()할 필요없어졌다.
이젠 new ArrayList로 주소값만 다르게 얻어와도 충분.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함