세트 복사 Java


83

복사하는 방법이 TreeSet있습니까? 즉, 갈 수 있습니까?

Set <Item> itemList;
Set <Item> tempList;

tempList = itemList;

아니면 물리적으로 세트를 반복하고 하나씩 복사해야합니까?


8
tempList.addAll(itemList)
dhblah

답변:


156

이를 수행하는 또 다른 방법은 복사 생성자 를 사용하는 것입니다 .

Collection<E> oldSet = ...
TreeSet<E> newSet = new TreeSet<E>(oldSet);

또는 빈 세트를 만들고 요소를 추가합니다.

Collection<E> oldSet = ...
TreeSet<E> newSet = new TreeSet<E>();
newSet.addAll(oldSet);

이와 달리 clone다른 집합 클래스, 다른 비교기를 사용하거나 다른 (설정되지 않은) 컬렉션 유형에서 채울 수도 있습니다.


복사의 결과 는 원본 인 경우 요소 인 객체에 대한 참조를 포함 Set하는 새로운 것 입니다. 요소 개체 자체는 복사되거나 복제되지 않습니다. 이는 Java API가 작동하도록 설계된 방식을 따릅니다 . 요소 객체를 복사하지 않습니다.SetSetCollection


7

Java 8 에서는 다음 항목을 사용 stream하고 collect복사 할 수 있습니다 .

Set<Item> newSet = oldSet.stream().collect(Collectors.toSet());

또는 다음으로 수집 할 수 있습니다 ImmutableSet(세트가 변경되어서는 안된다는 것을 알고있는 경우).

Set<Item> newSet = oldSet.stream().collect(ImmutableSet.toImmutableSet());

8
... 할 수 있지만 단순히 컬렉션을 복사하는 경우 복사 생성자 (etc)가 더 효율적이어야합니다.
Stephen C

3

@Stephen C가 제공하는 복사 생성자는 Set생성 한 파일 이있을 때 (또는 출처를 알 때) 이동하는 방법 입니다. 에서 오는 경우 사용중인 구현에 Map.entrySet()따라 다릅니다 Map.

findbugs 라고

entrySet () 메소드는 단일 Entry 객체가 반복되는 동안 재사용되고 반환되는 기본 맵의 뷰를 반환 할 수 있습니다. Java 1.6부터 IdentityHashMap과 EnumMap은 모두 그렇게했습니다. 이러한 맵을 반복 할 때 항목 값은 다음 반복으로 진행할 때까지만 유효합니다. 예를 들어, 그러한 entrySet를 addAll 메소드에 전달하려고하면 상황이 심각하게 잘못됩니다.

addAll()복사 생성자에 의해 호출 된 것처럼 마지막 항목 인 하나의 항목 만있는 집합을 찾을 수 있습니다.

Map그러나 모든 구현이 그렇게하는 것은 아니므로 구현이 안전하다는 것을 알고 있다면 복사 생성자가 확실히 갈 길입니다. 그렇지 않으면 새 Entry개체를 직접 만들어야 합니다.

Set<K,V> copy = new HashSet<K,V>(map.size());
for (Entry<K,V> e : map.entrySet())
    copy.add(new java.util.AbstractMap.SimpleEntry<K,V>(e));

편집 : Java 7 및 Java 6u45 (Stephen C 덕분에)에서 수행 한 테스트와 달리 findbugs 주석은 더 이상 적절하지 않은 것 같습니다. 이전 버전의 Java 6 (u45 이전)에서 그럴 수도 있지만 테스트 할 것이 없습니다.


1
관찰에 근거한 것입니까? 그렇다면 addAll구현 의 버그처럼 들립니다 . FWIW, Map내가 살펴본 구현은 모두 항목 집합을 반복하고 (일부 수준에서) 각 항목에 대한 키와 값을 추출합니다 . 항목 집합 반복기가 각각 동일한 객체를 반환 할 수 있다는 사실은 시간이 중요하지 않습니다. 내가 본 유일한 경우 EnumMap는 복사 생성자 자체가 항목을 복제하는 곳이었습니다 ... 소스 맵이 EnumMap.
Stephen C

1
@StephenC 당신이 옳은 것 같습니다 : 내가 수행 한 테스트는 IdentityHashMap그 버그로 이어지지 않습니다. 더 많은 문제는 Java 6u45에서 테스트했으며 문제가 없다는 것입니다. 나는 이것이 findbugs (또는 규칙을 기반으로 한 JDK)의 버그라고 생각합니다. 내 대답을 편집하겠습니다.
Matthieu 2015 년

3

Java 10 부터 :

Set<E> oldSet = Set.of();
Set<E> newSet = Set.copyOf(oldSet);

Set.copyOf()Set주어진의 요소를 포함 하는 수정 불가능한 것을 반환합니다 Collection.

주어진 Collection은이어야하며 요소를 null포함하지 않아야 null합니다.


2

자바 8 이상 :

Set<String> copy = new HashSet<>(mySet); 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.