Copiați o listă într-o altă listă din Java

1. Prezentare generală

În acest tutorial rapid, vom arăta diferite moduri de a copia o listă într-o altă listă și o eroare comună produsă în acest proces.

Pentru o introducere în utilizarea colecțiilor , vă rugăm să consultați acest articol aici.

2. Constructor

O modalitate simplă de a copia o Listă este folosind constructorul care ia ca argument o colecție:

List copy = new ArrayList(list);

Datorită faptului că copiem referințe aici și nu clonăm obiectele, fiecare modificare făcută într-un element va afecta ambele liste.

Din acest motiv, folosirea constructorului este bună pentru a copia obiecte imuabile:

List copy = new ArrayList(list);

Numărul întreg este o clasă imuabilă, valoarea sa este setată la crearea instanței și nu se poate schimba niciodată.

O referință la întreg poate fi astfel partajată de mai multe liste și fire și nu există nicio modalitate în care nimeni să-și poată schimba valoarea.

3. Listează ConcurrentAccessException

O problemă obișnuită care lucrează cu liste este ConcurrentAccessException . Acest lucru ar putea însemna că modificăm lista în timp ce încercăm să o copiem, cel mai probabil într-un alt fir.

Pentru a remedia această problemă, trebuie să fie:

  • Utilizați o colecție concepută pentru acces simultan
  • Blocați colecția în mod corespunzător pentru a o repeta
  • Găsiți o modalitate de a evita să copiați colecția originală

Având în vedere ultima noastră abordare, nu este sigură pentru fire. Deci, dacă dorim să ne rezolvăm problema cu prima opțiune, ar putea dori să folosim CopyOnWriteArrayList , în care toate operațiile mutative sunt implementate făcând o copie nouă a matricei de bază.

Pentru informații suplimentare, vă rugăm să consultați acest articol.

În cazul în care dorim să blocăm colecția , este posibil să folosim o primitivă de blocare pentru a serializa accesul de citire / scriere, cum ar fi ReentrantReadWriteLock .

4. Adăugați toate

O altă abordare pentru copierea elementelor este utilizarea metodei addAll :

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

Este important să rețineți când folosiți această metodă că, la fel ca și în cazul constructorului, conținutul ambelor liste va face referire la aceleași obiecte.

5. Colecții.copie

Colecții Clasa este formată exclusiv din metode statice , care operează pe colecții sau de returnare.

Una dintre ele este copierea , care are nevoie de o listă de surse și o listă de destinații cel puțin atât timp cât sursa.

Acesta va menține indexul fiecărui element copiat din lista de destinații, cum ar fi originalul:

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

În exemplul de mai sus, toate elementele anterioare din lista de destinații au fost suprascrise deoarece ambele liste au aceeași dimensiune.

În cazul în care dimensiunea listei de destinații este mai mare decât sursa:

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

Doar primele trei elemente au fost suprascrise, în timp ce restul elementelor din listă sunt conservate.

6. Utilizarea Java 8

Această versiune de Java ne deschide posibilitățile prin adăugarea de noi instrumente. Cel pe care îl vom explora în următoarele exemple este Stream :

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

Principalele avantaje ale acestui mod sunt oportunitatea de a utiliza skip și filtre. În exemplul următor vom sări peste primul element:

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

Este posibil să filtrăm și după lungimea șirului sau comparând un atribut al obiectelor noastre:

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

Este probabil că dorim să lucrăm într-un mod sigur:

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

Și săriți peste un element folosind și acest mod:

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

7. Utilizarea Java 10

În cele din urmă, una dintre ultimele versiuni Java ne permite să creăm o listă imuabilă care conține elementele colecției date :

List copy = List.copyOf(list);
Singurele condiții sunt ca colecția dată să nu fie nulă și să nu conțină niciun element nul.

8. Concluzie

În acest articol, am explorat diferite moduri de a copia o Listă într-o altă Listă cu diferite versiuni Java și o eroare comună produsă în acest proces. Ca întotdeauna, mostre de coduri pot fi găsite pe GitHub aici și aici.