Kopieren Sie eine Liste in eine andere Liste in Java

1. Übersicht

In diesem kurzen Tutorial werden verschiedene Möglichkeiten zum Kopieren einer Liste in eine andere Liste und ein häufig auftretender Fehler gezeigt.

Eine Einführung in die Verwendung von Sammlungen finden Sie in diesem Artikel hier.

2. Konstruktor

Eine einfache Möglichkeit, eine Liste zu kopieren, besteht darin, den Konstruktor zu verwenden, der eine Sammlung als Argument verwendet:

List copy = new ArrayList(list);

Aufgrund der Tatsache, dass wir hier die Referenz kopieren und die Objekte nicht klonen, wirken sich alle in einem Element vorgenommenen Änderungen auf beide Listen aus.

Aus diesem Grund ist die Verwendung des Konstruktors gut, um unveränderliche Objekte zu kopieren:

List copy = new ArrayList(list);

Integer ist eine unveränderliche Klasse. Ihr Wert wird beim Erstellen der Instanz festgelegt und kann sich nie ändern.

Eine Ganzzahlreferenz kann somit von mehreren Listen und Threads gemeinsam genutzt werden, und niemand kann ihren Wert ändern.

3. Listen Sie ConcurrentAccessException auf

Ein häufiges Problem beim Arbeiten mit Listen ist die ConcurrentAccessException . Dies kann bedeuten, dass wir die Liste ändern, während wir versuchen, sie zu kopieren, höchstwahrscheinlich in einem anderen Thread.

Um dieses Problem zu beheben, müssen wir entweder:

  • Verwenden Sie eine Sammlung für den gleichzeitigen Zugriff
  • Sperren Sie die Sammlung entsprechend, um sie zu durchlaufen
  • Finden Sie einen Weg, um zu vermeiden, dass Sie die Originalsammlung kopieren müssen

In Anbetracht unseres letzten Ansatzes ist es nicht threadsicher. Wenn wir unser Problem mit der ersten Option lösen möchten, möchten wir möglicherweise CopyOnWriteArrayList verwenden , in der alle mutativen Operationen implementiert werden, indem eine neue Kopie des zugrunde liegenden Arrays erstellt wird.

Weitere Informationen finden Sie in diesem Artikel.

Wenn wir die Sammlung sperren möchten , können Sie ein Sperrprimitiv verwenden, um den Lese- / Schreibzugriff zu serialisieren, z. B. ReentrantReadWriteLock .

4. AddAll

Ein anderer Ansatz zum Kopieren von Elementen ist die Verwendung der addAll- Methode:

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

Beachten Sie bei der Verwendung dieser Methode, dass der Inhalt beider Listen wie beim Konstruktor auf dieselben Objekte verweist.

5. Sammlungen.Kopie

Die Collections- Klasse besteht ausschließlich aus statischen Methoden, die Sammlungen bearbeiten oder zurückgeben.

Eine davon ist die Kopie , die eine Quellliste und eine Zielliste benötigt, die mindestens so lang sind wie die Quelle.

Der Index jedes kopierten Elements in der Zielliste wird beibehalten, z. B. das Original:

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

In dem obigen Beispiel werden alle vorherigen Elemente in der dest Liste überschrieben wurden , weil beide Listen die gleiche Größe haben.

Falls die Ziellistengröße größer als die Quelle ist:

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

Nur die drei ersten Elemente wurden überschrieben, während die restlichen Elemente in der Liste erhalten bleiben.

6. Verwenden von Java 8

Diese Version von Java eröffnet unsere Möglichkeiten durch Hinzufügen neuer Tools. Das, was wir in den nächsten Beispielen untersuchen werden, ist Stream :

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

Die Hauptvorteile dieser Art sind die Möglichkeit, Überspringen und Filter zu verwenden. Im nächsten Beispiel überspringen wir das erste Element:

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

Es ist auch möglich, nach der Länge des Strings zu filtern oder ein Attribut unserer Objekte zu vergleichen:

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

Es ist wahrscheinlich, dass wir nullsicher arbeiten möchten:

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

Und überspringen Sie ein Element auch auf diese Weise:

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

7. Verwenden von Java 10

Schließlich können wir mit einer der letzten Java-Versionen eine unveränderliche Liste erstellen, die die Elemente der angegebenen Sammlung enthält:

List copy = List.copyOf(list);
Die einzigen Bedingungen sind, dass die angegebene Sammlung nicht null sein darf und keine null Elemente enthalten darf.

8. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten zum Kopieren einer Liste in eine andere Liste mit unterschiedlichen Java- Versionen und einem dabei auftretenden häufigen Fehler untersucht. Wie immer finden Sie hier und hier Codebeispiele auf GitHub.