Kopieer een lijst naar een andere lijst in Java

1. Overzicht

In deze korte tutorial laten we verschillende manieren zien om een Lijst naar een ander Lijst en een veel voorkomende fout die tijdens het proces wordt geproduceerd.

Voor een inleiding in het gebruik van Collecties, verwijzen wij u naar dit artikel hier.

2. Constructeur

Een eenvoudige manier om een Lijst is door de constructor te gebruiken die een verzameling als argument heeft:

Lijstkopie = nieuwe ArrayList (lijst);

Vanwege het feit dat we hier referentie kopiëren en de objecten niet klonen, heeft elke wijziging die in één element wordt aangebracht, invloed op beide lijsten.

Om die reden is het gebruik van de constructor goed om onveranderlijke objecten te kopiëren:

Lijstkopie = nieuwe ArrayList (lijst);

Geheel getal is een onveranderlijke klasse, de waarde wordt ingesteld wanneer de instantie wordt gemaakt en kan nooit worden gewijzigd.

Een Geheel getal referentie kan dus worden gedeeld door meerdere lijsten en threads en niemand kan de waarde ervan wijzigen.

3. LijstConcurrentAccessException

Een veelvoorkomend probleem bij het werken met lijsten is het ConcurrentAccessException. Dit kan betekenen dat we de lijst aanpassen terwijl we deze proberen te kopiëren, hoogstwaarschijnlijk in een andere thread.

Om dit probleem op te lossen, moeten we:

  • Gebruik een collectie die is ontworpen voor gelijktijdige toegang
  • Vergrendel de verzameling op de juiste manier om deze te herhalen
  • Zoek een manier om te voorkomen dat u de originele collectie hoeft te kopiëren

Gezien onze laatste benadering, is het niet thread-safe. Dus als we ons probleem met de eerste optie willen oplossen, willen we misschien gebruiken CopyOnWriteArrayList, waarin alle mutatieve bewerkingen worden geïmplementeerd door een nieuwe kopie van de onderliggende array te maken.

Raadpleeg dit artikel voor meer informatie.

Voor het geval we het Verzamelingis het mogelijk om een ​​vergrendelingsprimitief te gebruiken om lees- / schrijftoegang te serialiseren, zoals ReentrantReadWriteLock.

4. Voeg alles toe

Een andere benadering om elementen te kopiëren is het gebruik van de Voeg alles toe methode:

Lijstkopie = nieuwe ArrayList (); copy.addAll (lijst);

Het is belangrijk om bij het gebruik van deze methode in gedachten te houden dat, net als bij de constructor, de inhoud van beide lijsten naar dezelfde objecten verwijst.

5. Collections.copy

De Collecties class bestaat uitsluitend uit statische methoden die op collecties werken of deze retourneren.

Een van hen is kopiëren, die een bronlijst en een bestemmingslijst nodig heeft die minstens zo lang is als de bron.

Het behoudt de index van elk gekopieerd element in de bestemmingslijst, zoals het origineel:

Lijstbron = Arrays.asList (1,2,3); Lijst dest = Arrays.asList (4,5,6); Collections.copy (bestemming, bron);

In het bovenstaande voorbeeld zijn alle voorgaande elementen in de dest lijst is overschreven omdat beide lijsten dezelfde grootte hebben.

In het geval dat de bestemmingslijst groter is dan de bron:

Lijstbron = Arrays.asList (1, 2, 3); Lijst dest = Arrays.asList (5, 6, 7, 8, 9, 10); Collections.copy (bestemming, bron);

Alleen de drie eerste items zijn overschreven, terwijl de rest van de elementen in de lijst behouden blijft.

6. Java 8 gebruiken

Deze versie van Java opent onze mogelijkheden door nieuwe tools toe te voegen. Degene die we in de volgende voorbeelden zullen onderzoeken is Stroom:

Lijstkopie = list.stream () .collect (Collectors.toList ());

De belangrijkste voordelen van deze manier zijn de mogelijkheid om skip en filters te gebruiken. In het volgende voorbeeld slaan we het eerste element over:

Lijst kopiëren = list.stream () .skip (1) .collect (Collectors.toList ());

Het is mogelijk om te filteren op de lengte van het Draad ook of door een attribuut van onze objecten te vergelijken:

Lijstkopie = list.stream () .filter (s -> s.length ()> 10) .collect (Collectors.toList ());
Lijst bloemen = list.stream () .filter (f -> f.getPetals ()> 6) .collect (Collectors.toList ());

Het is waarschijnlijk dat we op een nulveilige manier willen werken:

Lijstbloemen = Optioneel.ofNullable (lijst) .map (Lijst :: stream) .orElseGet (Stream :: leeg) .collect (Collectors.toList ());

En sla ook op deze manier een element over:

Lijstbloemen = Optioneel.ofNullable (lijst) .map (Lijst :: stream) .orElseGet (Stream :: leeg) .skip (1) .collect (Collectors.toList ());

7. Java 10 gebruiken

Ten slotte stelt een van de laatste Java-versies ons in staat om een ​​onveranderlijk Lijst met de elementen van het gegeven Verzameling:

List copy = List.copyOf (lijst);
De enige voorwaarden zijn dat de gegeven collectie niet null mag zijn en geen null-elementen mag bevatten.

8. Conclusie

In dit artikel hebben we verschillende manieren onderzocht om een Lijst naar een ander Lijst met verschillende Java versies en een veelvoorkomende fout die tijdens het proces is ontstaan. Zoals altijd zijn codevoorbeelden hier en hier op GitHub te vinden.