Pretvaranje kolekcije u ArrayList u Javi

1. Pregled

Pretvaranje Java kolekcija iz jedne vrste u drugu uobičajeni je programski zadatak. U ovom uputstvu pretvorit ćemo bilo koju vrstu Kolekcija do an ArrayList.

Kroz tutorial pretpostavit ćemo da već imamo zbirku Foo predmeta. Od tamo ćemo stvoriti ArrayList koristeći razne pristupe.

2. Definiranje našeg primjera

Ali prije nastavka, modelirajmo svoj ulaz i izlaz.

Naš izvor može biti bilo koja vrsta zbirke pa ćemo je prijaviti pomoću Kolekcija sučelje:

Zbirka srcCollection; 

Moramo proizvesti ArrayList s istim tipom elementa:

ArrayList newList;

3. Korištenje konstruktora ArrayList

Najjednostavniji način kopiranja kolekcije u novu kolekciju je korištenje njenog konstruktora.

U našem prethodnom vodiču za ArrayList saznali smo da ArrayList konstruktor može prihvatiti parametar zbirke:

ArrayList newList = novi ArrayList (srcCollection);
  • Novi ArrayList sadrži plitku kopiju Foo elemenata u izvornoj zbirci.
  • Redoslijed je isti kao u izvornoj zbirci.

Jednostavnost konstruktora čini ga izvrsnom opcijom u većini scenarija.

4. Korištenje Streams API-ja

Sada, iskoristimo Streams API za stvaranje ArrayList-a od postojeće Zbirke:

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

U ovom isječku:

  • Uzimamo tok iz izvorne kolekcije i primjenjujemo prikupiti() operator za stvaranje a Popis
  • Mi preciziramo ArrayList :: novo da dobijemo vrstu popisa koju želimo
  • Ovaj će kôd također proizvesti plitku kopiju.

Da nas ne brine točan Popis tipa, mogli bismo pojednostaviti:

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

Imajte na umu da toCollection () i izlistati() su statički uvezeni iz Kolekcionari. Da biste saznali više, pogledajte naš vodič o kolektorima Java 8.

5. Duboka kopija

Prije nego što smo spomenuli "plitke kopije". Pod tim mislimo na to elementi na novom popisu su potpuno isti Foo instance koji još uvijek postoje u izvornoj zbirci. Stoga smo kopirali Foos do newList referencom.

Ako izmijenimo sadržaj a Foo primjer u bilo kojoj zbirci koja izmjena će se odraziti u obje zbirke. Stoga, ako želimo izmijeniti elemente u bilo kojoj zbirci bez modificirajući drugu koja nam je potrebna za izvedbu "dubinske kopije".

Za dubinsko kopiranje a Foo, mi stvoriti potpuno novo Foo primjer za svaki element. Slijedom toga, svi Foo polja treba kopirati u nove instance.

Definirajmo svoje Foo klase kako bi se znao dubinski kopirati:

javna klasa Foo {private int id; privatni naziv niza; privatni roditelj Foo; javni Foo (int id, ime niza, roditelj Foo) {this.id = id; this.name = ime; this.parent = roditelj; } public Foo deepCopy () {return new Foo (this.id, this.name, this.parent! = null? this.parent.deepCopy (): null); }}

Ovdje možemo vidjeti polja iskaznica i Ime jesu int i Niz. Te se vrste podataka kopiraju po vrijednosti. Stoga ih jednostavno možemo dodijeliti.

The roditelj polje je drugo Foo, što je klasa. Ako Foo je mutiran, bilo koji kod koji dijeli tu referencu bio bi pogođen ovim promjenama. Moramo duboko kopirati roditelj polje.

Sada se možemo vratiti na naše ArrayList pretvorba. Samo nam treba karta operator za umetanje dubinske kopije u tok:

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

Sadržaj bilo koje zbirke možemo mijenjati bez utjecaja na drugu.

Dubinska kopija može biti dugotrajan postupak, ovisno o broju elemenata i dubini podataka. Korištenje paralelnog toka ovdje može potaknuti izvedbu ako je potrebno.

6. Kontrola redoslijeda popisa

Prema zadanim postavkama, naš će tok isporučivati ​​elemente u naš ArrayList istim redoslijedom kojim se susreću u izvornoj zbirci.

Ako želimo promijeniti taj redoslijed mogli bismo primijeniti sortirano () operatora do potoka. Da razvrstamo naše Foo predmeti po imenu:

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

Dodatne detalje o naručivanju streama možemo pronaći u ovom ranijem vodiču.

7. Zaključak

The ArrayList konstruktor je učinkovit način za dobivanje sadržaja a Kolekcija u novu ArrayList.

Međutim, ako trebamo doraditi rezultirajući popis, Streams API nudi moćan način za izmjenu postupka.

Kôd korišten u ovom članku u cijelosti se može naći na GitHubu.