Eine Collection in Java in ArrayList konvertieren

Konvertieren einer Auflistung in ArrayList in Java

1. Überblick

Das Konvertieren von Java-Sammlungen von einem Typ in einen anderen ist eine häufige Programmieraufgabe. In diesem Tutorial konvertieren wir alle Arten vonCollection inArrayList.

Während des gesamten Tutorials gehen wir davon aus, dass wir bereits eine Sammlung vonFoo-Objekten haben. Von dort aus erstellen wir einArrayList , das verschiedene Ansätze unterstützt.

2. Unser Beispiel definieren

Bevor wir fortfahren, modellieren wir jedoch unsere Ein- und Ausgabe.

Unsere Quelle kann jede Art von Sammlung sein, daher deklarieren wir sie über dieCollection-Schnittstelle:

Collection srcCollection;

Wir müssen einArrayList mit demselben Elementtyp erzeugen:

ArrayList newList;

3. Verwenden des ArrayList-Konstruktors

Der einfachste Weg, eine Sammlung in eine neue Sammlung zu kopieren, ist die Verwendung ihres Konstruktors.

In unseren vorherigenguide to ArrayList haben wir gelernt, dass der KonstruktorArrayList einen Auflistungsparameter akzeptieren kann:

ArrayList newList = new ArrayList<>(srcCollection);
  • Das neueArrayList enthält eine flache Kopie der Foo-Elemente in der Quellensammlung.

  • Die Reihenfolge ist dieselbe wie in der Quellensammlung.

Die Einfachheit des Konstruktors macht ihn in den meisten Szenarien zu einer großartigen Option.

4. Verwenden der Streams-API

Nun,let’s take advantage of the Streams API to create an ArrayList from an existing Collection: _ _

ArrayList newList = srcCollection.stream().collect(toCollection(ArrayList::new));

In diesem Ausschnitt:

  • Wir nehmen den Stream aus der Quellensammlung und wenden den Operatorcollect() an, umList zu erstellen

  • Wir gebenArrayList::new an, um den gewünschten Listentyp zu erhalten

  • Dieser Code erzeugt auch eine flache Kopie.

Wenn wir uns nicht um den genauenList-Typ kümmern würden, könnten wir vereinfachen:

List newList = srcCollection.stream().collect(toList());

Beachten Sie, dasstoCollection() undtoList() statisch ausCollectors importiert werden. Weitere Informationen finden Sie in unserenguide on Java 8’s Collectors.

5. Deep Copy

Vorher haben wir „flache Kopien“ erwähnt. Damit meinen wir, dassthe elements in the new list are exactly the same Foo instances noch in der Quellensammlung vorhanden sind. Daher haben wir dieFoos als Referenz in dienewList kopiert.

Wenn wir den Inhalt einerFoo-Instanz in einer der beiden Sammlungen ändern, istmodification will be reflected in both collections. Wenn wir also die Elemente in einer der beiden Auflistungenwithout ändern möchten, müssen wir eine "tiefe Kopie" durchführen.

Um einFoo tief zu kopieren, haben wircreate a completely new Foo instance for each element. Folglich müssen alleFoo-Felder in die neuen Instanzen kopiert werden.

Definieren wir die KlasseFooo, dass sie weiß, wie sie sich selbst tief kopiert:

public class Foo {

    private int id;
    private String name;
    private Foo parent;

    public Foo(int id, String name, Foo parent) {
        this.id = id;
        this.name = name;
        this.parent = parent;
    }

    public Foo deepCopy() {
        return new Foo(
          this.id, this.name, this.parent != null ? this.parent.deepCopy() : null);
    }
}

Hier sehen wir, dass die Felderid undnameint undString sind. Diese Datentypen werden nach Wert kopiert. Daher können wir einfach beide zuweisen.

Das Feldparent ist ein weiteresFoo, bei dem es sich um eine Klasse handelt. WennFoo got mutiert, wäre jeder Code, der diese Referenz teilt, von diesen Änderungen betroffen. We have to deep copy the parent field.

Jetzt können wir zur Konvertierung vonArrayListzurückkehren. We just need the map operator to insert the deep copy in den Durchfluss:

ArrayList newList = srcCollection.stream()
  .map(foo -> foo.deepCopy())
  .collect(toCollection(ArrayList::new));

Wir können den Inhalt einer Sammlung ändern, ohne die andere zu beeinflussen.

Eine tiefe Kopie kann abhängig von der Anzahl der Elemente und der Tiefe der Daten ein langwieriger Prozess sein. Wenn Sie hier einen parallelen Stream verwenden, kann dies bei Bedarf zu einer Leistungssteigerung führen.

6. Steuern der Listenreihenfolge

Standardmäßig liefert unser Stream Elemente an unsereArrayList in derselben Reihenfolge, in der sie in der Quellensammlung vorkommen.

Wenn wir diese Reihenfolge ändern wollenwe could apply the sorted() operator to the stream. So sortieren Sie die Objekte unsererFoonach Namen:

ArrayList newList = srcCollection.stream()
  .sorted(Comparator.comparing(Foo::getName))
  .collect(toCollection(ArrayList::new));

Weitere Details zur Stream-Bestellung finden Sie inearlier tutorial.

7. Fazit

Der KonstruktorArrayList ist ein effektiver Weg, um den Inhalt vonCollection in ein neuesArrayList zu bringen.

Wenn wir jedoch die resultierende Liste optimieren müssen, bietet die Streams-API eine leistungsstarke Möglichkeit, den Prozess zu ändern.

Der in diesem Artikel verwendete Code befindet sich in seiner Gesamtheit inover on GitHub.