Konvertering af en samling til ArrayList i Java

1. Oversigt

Konvertering af Java-samlinger fra en type til en anden er en almindelig programmeringsopgave. I denne vejledning konverterer vi enhver type Kollektion til en ArrayList.

I hele tutorialen antager vi, at vi allerede har en samling af Foo genstande. Derfra opretter vi en ArrayList ved hjælp af forskellige tilgange.

2. Definition af vores eksempel

Men inden vi fortsætter, lad os modellere vores input og output.

Vores kilde kan være enhver form for samling, så vi erklærer det ved hjælp af Kollektion grænseflade:

Samling srcCollection; 

Vi er nødt til at producere en ArrayList med samme elementtype:

ArrayList newList;

3. Brug af ArrayList Constructor

Den enkleste måde at kopiere en samling til en ny samling er at bruge dens konstruktør.

I vores tidligere guide til ArrayList lærte vi, at ArrayList konstruktør kan acceptere en indsamlingsparameter:

ArrayList newList = ny ArrayList (srcCollection);
  • Den nye ArrayList indeholder en lav kopi af Foo-elementerne i kildesamlingen.
  • Ordren er den samme som en i kildesamlingen.

Konstruktørens enkelhed gør det til en god mulighed i de fleste scenarier.

4. Brug af Streams API

Nu, lad os drage fordel af Streams API til at oprette en ArrayList fra en eksisterende samling:

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

I dette uddrag:

  • Vi tager strømmen fra kildesamlingen og anvender indsamle() operatør til at oprette en Liste
  • Vi specificerer ArrayList :: nyt for at få den listetype, vi ønsker
  • Denne kode producerer også en lav kopi.

Hvis vi ikke var bekymrede over det nøjagtige Liste type, kunne vi forenkle:

Liste over newList = srcCollection.stream (). Collect (toList ());

Noter det toCollection () og toList () importeres statisk fra Samlere. For at lære mere henvises til vores guide til Java 8s samlere.

5. Dyb kopi

Før vi nævnte "overfladiske kopier". Med det mener vi det elementerne i den nye liste er nøjagtigt de samme Foo tilfælde der stadig findes i kildesamlingen. Derfor har vi kopieret Foos til newList som reference.

Hvis vi ændrer indholdet af en Foo eksempel i begge samlinger ændring afspejles i begge samlinger. Derfor, hvis vi vil ændre elementerne i begge samlinger uden ændre den anden, vi har brug for for at udføre en "dyb kopi."

Til dybkopiering a Foo, vi skabe et helt nyt Foo eksempel for hvert element. Derfor er alle de Foo felter skal kopieres til de nye forekomster.

Lad os definere vores Foo klasse, så den ved, hvordan man dybt kopierer sig selv:

offentlig klasse Foo {privat int id; privat strengnavn; privat Foo forælder; offentlig Foo (int id, String name, Foo parent) {this.id = id; dette.navn = navn; this.parent = forælder; } offentlig Foo deepCopy () {returner ny Foo (this.id, this.name, this.parent! = null? this.parent.deepCopy (): null); }}

Her kan vi se markerne id og navn er int og Snor. Disse datatyper kopieres efter værdi. Derfor kan vi simpelthen tildele dem begge.

Det forælder felt er en anden Foo, som er en klasse. Hvis Foo blev muteret, enhver kode, der deler denne reference, vil blive påvirket af disse ændringer. Vi er nødt til dybt at kopiere forælder Mark.

Nu kan vi vende tilbage til vores ArrayList konvertering. Vi har bare brug for kort operatøren til at indsætte den dybe kopi ind i strømmen:

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

Vi kan ændre indholdet af begge samlinger uden at påvirke den anden.

En dyb kopi kan være en langvarig proces afhængig af antallet af elementer og dybden af ​​dataene. Brug af en parallel stream her kan give et ydeevne boost, hvis det er nødvendigt.

6. Kontrol af listeordren

Som standard vil vores stream levere elementer til vores ArrayList i samme rækkefølge som de er stødt på i kildesamlingen.

Hvis vi vil ændre den rækkefølge vi kunne anvende sorteret () operatør til strømmen. At sortere vores Foo objekter ved navn:

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

Vi kan finde flere detaljer om strømbestilling i denne tidligere vejledning.

7. Konklusion

Det ArrayList konstruktør er en effektiv måde at få indholdet af en Kollektion ind i et nyt ArrayList.

Men hvis vi har brug for at finjustere den resulterende liste, giver Streams API en effektiv måde at ændre processen på.

Koden, der bruges i denne artikel, kan findes i sin helhed på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found