Подтвердить что ты не робот

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

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

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

tempList = itemList;

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

4b9b3361

Ответ 1

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

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

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

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

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


Note that the result of copying a [TG43] is a new [TG44] containing references to the objects that are elements if the original [TG45]. The element objects themselves are not copied or cloned. This conforms with the way that the Java [TG46] APIs are designed to work: they don't copy the element objects.

Ответ 2

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

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

Или вы можете собрать в ImmutableSet (если вы знаете, что набор не должен меняться):

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

Ответ 3

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

findbugs говорит

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

Ответ 4

Начиная с Java 10:

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

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

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

Ответ 5

Java 8+:

Set<String> copy = new HashSet<>(mySet);