본문 바로가기

언어/Java

[ Java ] List 복사하기

반응형

Java에서 List의 내용을 복사하는 방법은 여러 가지가 있습니다. List를 복사할 때 중요한 것은 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)의 차이를 이해하는 것입니다.

  • 얕은 복사(Shallow Copy): 리스트의 원소들에 대한 참조만 복사합니다. 즉, 원본 리스트와 복사된 리스트는 동일한 객체를 참조합니다.
  • 깊은 복사(Deep Copy): 리스트의 원소들까지 새롭게 복사하여 원본과 복사된 리스트가 독립적인 객체를 갖도록 합니다.

1. 얕은 복사(Shallow Copy)

얕은 복사를 수행하는 간단한 방법은 ArrayList의 생성자나 Collections.copy 메서드를 사용하는 것입니다.

예시: ArrayList 생성자 사용

import java.util.ArrayList;
import java.util.List;

public class ShallowCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 얕은 복사
        List<String> shallowCopy = new ArrayList<>(originalList);

        System.out.println("Original List: " + originalList);
        System.out.println("Shallow Copy: " + shallowCopy);

        // 원본 리스트 변경
        originalList.set(0, "Avocado");

        System.out.println("Modified Original List: " + originalList);
        System.out.println("Shallow Copy after modification: " + shallowCopy);
    }
}

예시: Collections.copy 사용

Collections.copy는 미리 크기가 설정된 리스트에 복사할 수 있습니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ShallowCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 크기가 동일한 빈 리스트 생성
        List<String> shallowCopy = new ArrayList<>(originalList.size());
        Collections.addAll(shallowCopy, new String[originalList.size()]);

        // 얕은 복사
        Collections.copy(shallowCopy, originalList);

        System.out.println("Original List: " + originalList);
        System.out.println("Shallow Copy: " + shallowCopy);

        // 원본 리스트 변경
        originalList.set(0, "Avocado");

        System.out.println("Modified Original List: " + originalList);
        System.out.println("Shallow Copy after modification: " + shallowCopy);
    }
}

2. 깊은 복사(Deep Copy)

깊은 복사를 수행하려면 리스트의 각 원소를 개별적으로 복사해야 합니다. 이 작업은 복제할 객체가 Cloneable 인터페이스를 구현했거나, 각 객체의 복제 생성자를 호출하는 방법으로 수행할 수 있습니다.

예시: Cloneable 인터페이스 사용

Cloneable 인터페이스를 구현하는 객체를 복사하는 예시입니다.

import java.util.ArrayList;
import java.util.List;

class Fruit implements Cloneable {
    String name;

    public Fruit(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return name;
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        List<Fruit> originalList = new ArrayList<>();
        originalList.add(new Fruit("Apple"));
        originalList.add(new Fruit("Banana"));
        originalList.add(new Fruit("Cherry"));

        // 깊은 복사
        List<Fruit> deepCopy = new ArrayList<>();
        for (Fruit fruit : originalList) {
            try {
                deepCopy.add((Fruit) fruit.clone());
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Original List: " + originalList);
        System.out.println("Deep Copy: " + deepCopy);

        // 원본 리스트의 객체 수정
        originalList.get(0).name = "Avocado";

        System.out.println("Modified Original List: " + originalList);
        System.out.println("Deep Copy after modification: " + deepCopy);
    }
}

예시: 복제 생성자 사용

각 객체가 자체적으로 복제 생성자를 제공하는 경우

import java.util.ArrayList;
import java.util.List;

class Fruit {
    String name;

    public Fruit(String name) {
        this.name = name;
    }

    // 복제 생성자
    public Fruit(Fruit another) {
        this.name = another.name;
    }

    @Override
    public String toString() {
        return name;
    }
}

public class DeepCopyExample {
    public static void main(String[] args) {
        List<Fruit> originalList = new ArrayList<>();
        originalList.add(new Fruit("Apple"));
        originalList.add(new Fruit("Banana"));
        originalList.add(new Fruit("Cherry"));

        // 깊은 복사
        List<Fruit> deepCopy = new ArrayList<>();
        for (Fruit fruit : originalList) {
            deepCopy.add(new Fruit(fruit));
        }

        System.out.println("Original List: " + originalList);
        System.out.println("Deep Copy: " + deepCopy);

        // 원본 리스트의 객체 수정
        originalList.get(0).name = "Avocado";

        System.out.println("Modified Original List: " + originalList);
        System.out.println("Deep Copy after modification: " + deepCopy);
    }
}

요약

  • 얕은 복사: 리스트 객체 자체만 복사하고 내부 객체는 동일한 참조를 유지합니다.
  • 깊은 복사: 리스트 내부의 객체도 모두 새롭게 복사하여 원본과 독립적인 객체를 생성합니다.

복사 방식은 리스트에 포함된 객체의 특성에 따라 결정해야 하며, 각각의 경우에 대해 신중하게 고려해야 합니다.

반응형

'언어 > Java' 카테고리의 다른 글

[ Java ] 조건문 if  (1) 2024.06.17
[ Java ] ClassPath 설정하기  (0) 2024.06.15
[ Java ] List 사용하기  (1) 2024.06.13
[ Java ] 자바 대입연산자 사용하기  (1) 2024.06.09
[ Java ] 삼항 연산자 사용해보기  (0) 2024.06.09