Konvertering av en samling til ArrayList i Java

1. Oversikt

Konvertering av Java-samlinger fra en type til en annen er en vanlig programmeringsoppgave. I denne opplæringen konverterer vi alle typer Samling til en ArrayList.

Gjennom opplæringen vil vi anta at vi allerede har en samling av Foo gjenstander. Derfra oppretter vi en ArrayList ved hjelp av ulike tilnærminger.

2. Definere vårt eksempel

Men før vi fortsetter, la oss modellere våre input og output.

Kilden vår kan være hvilken som helst type samling, så vi vil erklære den ved hjelp av Samling grensesnitt:

Samling srcCollection; 

Vi trenger å produsere en ArrayList med samme elementtype:

ArrayList newList;

3. Bruke ArrayList Constructor

Den enkleste måten å kopiere en samling til en ny samling er å bruke konstruktøren.

I vår forrige guide til ArrayList lærte vi at ArrayList konstruktør kan godta en samlingsparameter:

ArrayList newList = ny ArrayList (srcCollection);
  • Den nye ArrayList inneholder en grunne kopi av Foo-elementene i kildesamlingen.
  • Bestillingen er den samme som en i kildesamlingen.

Enkelheten til konstruktøren gjør det til et flott alternativ i de fleste scenarier.

4. Bruke Streams API

Nå, la oss dra nytte av Streams API for å opprette en ArrayList fra en eksisterende samling:

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

I dette utdraget:

  • Vi tar strømmen fra kildesamlingen og bruker samle inn() operatør for å lage en Liste
  • Vi spesifiserer ArrayList :: ny for å få den listetypen vi ønsker
  • Denne koden vil også produsere en grunne kopi.

Hvis vi ikke var bekymret for det nøyaktige Liste type, kan vi forenkle:

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

Noter det toCollection () og å liste opp() importeres statisk fra Samlere. For å lære mer, se vår guide om Java 8s samlere.

5. Dyp kopi

Før vi nevnte “grunne eksemplarer”. Med det mener vi det elementene i den nye listen er nøyaktig de samme Foo tilfeller som fremdeles finnes i kildesamlingen. Derfor har vi kopiert Foos til newList som referanse.

Hvis vi endrer innholdet i en Foo forekomst i begge samlingene som endring vil gjenspeiles i begge samlingene. Derfor, hvis vi vil endre elementene i begge samlingene uten endre den andre vi trenger for å utføre en "dyp kopi."

Til dypkopiering a Foo, vi lage et helt nytt Foo forekomst for hvert element. Derfor, alle Foo felt må kopieres til de nye forekomstene.

La oss definere vår Foo klasse slik at den vet hvordan å kopiere seg selv:

offentlig klasse Foo {privat int id; privat strengnavn; privat Foo-foreldre; offentlig Foo (int id, strengnavn, Foo foreldre) {this.id = id; this.name = navn; this.parent = foreldre; } public Foo deepCopy () {return new Foo (this.id, this.name, this.parent! = null? this.parent.deepCopy (): null); }}

Her kan vi se feltene id og Navn er int og String. Disse datatypene kopieres etter verdi. Derfor kan vi ganske enkelt tildele dem begge.

De foreldre felt er et annet Foo, som er en klasse. Hvis Foo ble mutert. Enhver kode som deler referansen, vil bli påvirket av disse endringene. Vi må dypt kopiere foreldre felt.

Nå kan vi komme tilbake til vår ArrayList omdannelse. Vi trenger bare kart operatøren for å sette inn den dype kopien inn i flyten:

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

Vi kan endre innholdet i den ene samlingen uten å påvirke den andre.

En dyp kopi kan være en langvarig prosess avhengig av antall elementer og dybden på dataene. Bruk av en parallell strøm her kan gi et ytelsesløft om nødvendig.

6. Kontrollere listeordren

Som standard vil strømmen vår levere elementer til vår ArrayList i samme rekkefølge som de oppstår i kildesamlingen.

Hvis vi vil endre den rekkefølgen vi kunne bruke sortert () operatør til strømmen. Å sortere våre Foo objekter etter navn:

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

Vi kan finne ytterligere detaljer om strømbestilling i denne tidligere opplæringen.

7. Konklusjon

De ArrayList konstruktør er en effektiv måte å få innholdet i Samling inn i en ny ArrayList.

Imidlertid, hvis vi trenger å tilpasse den resulterende listen, gir Streams API en kraftig måte å endre prosessen på.

Koden som brukes i denne artikkelen finner du i sin helhet på GitHub.


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