Копирование наборов Java - PullRequest
       10

Копирование наборов Java

76 голосов
/ 24 сентября 2011

Есть ли способ скопировать TreeSet?То есть можно пойти

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

tempList = itemList;

или вам нужно физически перебирать наборы и копировать их один за другим?

Ответы [ 4 ]

144 голосов
/ 24 сентября 2011

Другой способ сделать это - использовать конструктор копирования :

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

Или создайте пустой набор и добавьте элементы:

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

В отличие от clone они позволяют вам использовать другой класс набора, другой компаратор или даже заполнять из другого (не заданного) типа коллекции.


Обратите внимание, что результатом копирования Set является новый Set, содержащий ссылки на объекты, являющиеся элементами, если оригинал Set. Сами объекты элемента не копируются и не клонируются. Это соответствует способу работы API-интерфейсов Java Collection: они не копируют объекты-элементы.

5 голосов
/ 11 октября 2017

В Java 8 вы можете использовать stream и collect для копирования элементов:

Set<Item> newSet = oldSet.stream().collect(Collectors.toSet());
3 голосов
/ 26 июня 2018

Начиная с Java 10 :

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

Set.copyOf() возвращает неизменяемое Set, содержащее элементы данного Collection.

Указанный Collection не должен быть null и не должен содержать никаких элементов null.

3 голосов
/ 18 сентября 2015

Конструктор копирования, данный @Stephen C, - это путь, когда у вас есть Set, который вы создали (или когда вы знаете, откуда он). Когда речь идет о Map.entrySet(), это будет зависеть от используемой реализации Map:

findbugs говорит

Метод entrySet () может возвращать представление базового Карта, на которой один объект Entry используется повторно и возвращается во время итерация. Начиная с Java 1.6, IdentityHashMap и EnumMap делали это. При итерации по такой карте значение Entry будет действительным только до Вы переходите к следующей итерации. Если, например, вы пытаетесь пройти такая запись устанавливает метод 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 (благодаря Стивену С), комментарий findbugs больше не выглядит уместным. Возможно, это имело место в более ранних версиях Java 6 (до u45), но мне не нужно ничего тестировать.

...