Скопировать список в другой список на Java

Скопировать список в другой список на Java

1. обзор

В этом кратком руководстве мы покажем различные способы копированияList в другойList и типичные ошибки, возникающие в процессе.

Для введения в использованиеCollections см.to this article here.

2. Конструктор

Простой способ скопироватьList - использовать конструктор, который принимает коллекцию в качестве аргумента:

List copy = new ArrayList<>(list);

Из-за того, что мы копируем здесь ссылку, а не клонируем объекты, каждое исправление, внесенное в один элемент, повлияет на оба списка.

По этой причине использование конструктора полезно для копирования неизменяемых объектов:

List copy = new ArrayList<>(list);

Integer - неизменяемый класс, его значение устанавливается при создании экземпляра и никогда не может измениться.

Таким образом, ссылкаInteger может использоваться несколькими списками и потоками, и никто не может изменить ее значение.

3. ListConcurrentAccessException

A common problem working with lists is the ConcurrentAccessException. Это может означать, что мы изменяем список, пока пытаемся скопировать его, скорее всего, в другом потоке.

Чтобы решить эту проблему, мы должны либо:

  • Использовать разработанный для одновременного сбора доступа

  • Зафиксируйте коллекцию соответствующим образом, чтобы выполнить итерацию

  • Найдите способ избежать необходимости копировать оригинальную коллекцию

Учитывая наш последний подход, он не является потокобезопасным. Так что, если мы хотим решить нашу проблему с помощью первого варианта, мы можем использоватьCopyOnWhiteArrayList, в котором все изменяющие операции реализованы путем создания новой копии базового массива.

Для получения дополнительной информации обратитесь кto this article.

Если мы хотим заблокироватьCollection, можно использовать примитив блокировки для сериализации доступа для чтения / записи, напримерReentrantReadWriteLock.

4. AddAllс

Другой подход к копированию элементов - использование методаaddAll:

List copy = new ArrayList<>();
copy.addAll(list);

При использовании этого метода важно помнить, что, как и в случае с конструктором, содержимое обоих списков будет ссылаться на одни и те же объекты.

5. Collections.copyс

КлассCollections состоит исключительно из статических методов, которые работают с коллекциями или возвращают их.

Один из них -copy, которому нужен список источников и список адресатов, по крайней мере, такой же длины, как и источник.

Он будет поддерживать индекс каждого скопированного элемента в списке адресатов, например в оригинале:

List source = Arrays.asList(1,2,3);
List dest = Arrays.asList(4,5,6);
Collections.copy(dest, source);

В приведенном выше примере все предыдущие элементы в спискеdest были перезаписаны, потому что оба списка имеют одинаковый размер.

В случае, если размер списка адресатов больше, чем источник:

List source = Arrays.asList(1, 2, 3);
List dest = Arrays.asList(5, 6, 7, 8, 9, 10);
Collections.copy(dest, source);

Только три первых элемента были перезаписаны, а остальные элементы в списке сохранены.

6. Использование Java 8

Эта версия Java открывает наши возможности, добавляя новые инструменты. В следующих примерах мы рассмотримStream:

List copy = list.stream()
  .collect(Collectors.toList());

Основными преимуществами этого способа являются возможность использования скипа и фильтров. В следующем примере мы пропустим первый элемент:

List copy = list.stream()
  .skip(1)
  .collect(Collectors.toList());

Также можно фильтровать по длинеString или сравнивая атрибут наших объектов:

List copy = list.stream()
  .filter(s -> s.length() > 10)
  .collect(Collectors.toList());
List flowers = list.stream()
  .filter(f -> f.getPetals() > 6)
  .collect(Collectors.toList());

Вероятно, мы хотим работать нулевым способом:

List flowers = Optional.ofNullable(list)
  .map(List::stream)
  .orElseGet(Stream::empty)
  .collect(Collectors.toList());

И пропустите элемент, используя этот способ тоже:

List flowers = Optional.ofNullable(list)
  .map(List::stream).orElseGet(Stream::empty)
  .skip(1)
  .collect(Collectors.toList());

7. Использование Java 10

Наконец, одна из последних версий Java позволяет нам создавать неизменяемыйList, содержащий элементы данногоCollection:

List copy = List.copyOf(list);

Единственные условия: данная Коллекция не должна быть нулевой и не должна содержать никаких нулевых элементов.

8. Заключение

В этой статье мы изучили различные способы копированияList в другойList с разными версиямиJava и типичную ошибку, возникающую в процессе.

Как всегда, образцы кода можно найти на GitHubhere иhere.