Копирайте списък в друг списък в Java

1. Общ преглед

В този бърз урок ще покажем различни начини за копиране на списък в друг списък и често срещана грешка, получена в процеса.

За въведение в използването на колекции , моля, вижте тази статия тук.

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

Лесен начин за копиране на Списък е чрез използване на конструктора, който приема колекция като свой аргумент:

List copy = new ArrayList(list);

Поради факта, че копираме референция тук и не клонираме обектите, всяко изменение в един елемент ще повлияе и на двата списъка.

Поради тази причина използването на конструктора е добре да копирате неизменяеми обекти:

List copy = new ArrayList(list);

Integer е неизменим клас, стойността му се задава при създаването на екземпляра и никога не може да се промени.

По този начин референция за цяло число може да се споделя от множество списъци и нишки и няма начин някой да промени стойността му.

3. Списък на ConcurrentAccessException

Често срещан проблем при работа със списъци е ConcurrentAccessException . Това може да означава, че модифицираме списъка, докато се опитваме да го копираме, най-вероятно в друга тема.

За да коригираме този проблем, трябва:

  • Използвайте проектиран за едновременно събиране на достъп
  • Заключете колекцията по подходящ начин, за да я повторите
  • Намерете начин да избегнете необходимостта от копиране на оригиналната колекция

Имайки предвид последния ни подход, той не е безопасен за нишките. Така че, ако искаме да разрешим проблема си с първата опция, може да поискаме да използваме CopyOnWriteArrayList , в който всички мутативни операции се изпълняват чрез създаване на ново копие на базовия масив.

За повече информация вижте тази статия.

В случай, че искаме да заключим колекцията , възможно е да използваме примитив за заключване, за да сериализираме достъп за четене / запис, като ReentrantReadWriteLock .

4. AddAll

Друг подход за копиране на елементи е използването на метода addAll :

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

Важно е да имате предвид, когато използвате този метод, че както при конструктора, съдържанието на двата списъка ще се позовава на едни и същи обекти.

5. Колекции.копия

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

Едно от тях е копие , което се нуждае от списък с източници и списък с дестинации поне толкова дълго, колкото източника.

Той ще поддържа индекса на всеки копиран елемент в списъка с местоназначения, като оригинала:

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 copy = List.copyOf(list);
Единствените условия са дадената колекция да не е нула и да не съдържа никакви нулеви елементи.

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

В тази статия разгледахме различни начини за копиране на списък в друг списък с различни версии на Java и често срещана грешка, получена в процеса. Както винаги, примерни кодове могат да бъдат намерени в GitHub тук и тук.