Java pogodne tvorničke metode za zbirke

1. Pregled

Java 9 donosi dugo očekivani sintaktički šećer za stvaranje malih, neizmijenjivih Kolekcija slučajevi koji koriste jednoslojni sažeti kod. Prema JEP 269, nove pogodne tvorničke metode bit će uključene u JDK 9.

U ovom ćemo članku pokriti njegovu upotrebu zajedno s detaljima implementacije.

2. Povijest i motivacija

Stvaranje male nepromjenjive Kolekcija na Javi je vrlo opširan na tradicionalan način.

Uzmimo primjer a Postavi:

Set set = new HashSet (); set.add ("foo"); set.add ("traka"); set.add ("baz"); set = Collections.unmodifiableSet (set);

To je previše koda za jednostavan zadatak i to bi trebalo biti moguće učiniti jednim izrazom.

Navedeno vrijedi i za a Karta.

Međutim, za Popis, postoji tvornička metoda:

Lista popisa = Arrays.asList ("foo", "bar", "baz");

Iako ovo Popis Stvaranje je bolje od inicijalizacije konstruktora, to je manje očito jer uobičajena intuicija ne bi trebala tražiti Nizovi razred za metode za stvaranje a Popis:

Postoje i drugi načini smanjenja opširnosti poput dvostruka zagrada inicijalizacija tehnika:

Set set = Collections.unmodifiableSet (novi HashSet () {{add ("foo"); add ("bar"); add ("baz");}});

ili pomoću Java 8 Potoci:

Stream.of ("foo", "bar", "baz") .collect (collectionAndThen (toSet (), Collections :: unmodifiableSet));

Tehnika dvostruke zagrade samo je malo manje opširna, ali uvelike smanjuje čitljivost (i smatra se anti-uzorkom).

Inačica Java 8, međutim, izraz je u jednom retku, a ima i nekih problema. Prvo, nije očito i intuitivno. Drugo, to je još uvijek opširno. Treće, uključuje stvaranje nepotrebnih predmeta. I četvrto, ova metoda se ne može koristiti za stvaranje a Karta.

Da sumiramo nedostatke, niti jedan od gore navedenih pristupa ne tretira specifični slučaj upotrebe stvarajući mali nemodificirani Kolekcija prvorazredni problem klase.

3. Opis i upotreba

Osigurane su statičke metode Popis, Postavi, i Karta sučelja koja uzimaju elemente kao argumente i vraćaju instancu Popis, Postavi, i Karta, odnosno.

Ova metoda je imenovana od(…) za sva tri sučelja.

3.1. Popis i Postavi

Potpis i karakteristike Popis i Postavi tvorničke metode su iste:

statički popis (E e1, E e2, E e3) statičkog skupa (E e1, E e2, E e3)

korištenje metoda:

Lista popisa = List.of ("foo", "bar", "baz"); Set set = Set.of ("foo", "bar", "baz");

Kao što vidimo, vrlo je jednostavno, kratko i sažeto.

U primjeru smo koristili metodu koja uzima točno tri elementa kao parametre i vraća a Popis / Postavi veličine 3.

No, postoji 12 preopterećenih verzija ove metode - jedanaest s 0 do 10 parametara i jedna s var-args:

statički popis () statički popis (E e1) statički popis (E e1, E e2) // .... i tako dalje statički popis (E ... elems)

Za većinu praktičnih svrha bilo bi dovoljno 10 elemenata, ali ako je potrebno više, može se koristiti verzija var-args.

Sad se možemo pitati koja je svrha imati 11 dodatnih metoda ako postoji verzija var-args koja može raditi za bilo koji broj elemenata.

Odgovor na to je izvedba. Svaki poziv metode var-args implicitno stvara niz. Preopterećenim metodama izbjegava se nepotrebno stvaranje predmeta i skupljanje smeća. Baš suprotno, Nizovi.asList uvijek stvara taj implicitni niz i, prema tome, manje je učinkovit kada je broj elemenata nizak.

Tijekom stvaranja a Postavi pomoću tvorničke metode, ako se duplicirani elementi predaju kao parametri, tada IlegalArgumentException bačen u vrijeme izvođenja:

@Test (očekuje se = IllegalArgumentException.class) javna praznina onDuplicateElem_IfIllegalArgExp_thenSuccess () {Set.of ("foo", "bar", "baz", "foo"); }

Ovdje je važno napomenuti da je, budući da tvorničke metode koriste generičke lijekove, primitivni tipovi dobivaju autobox.

Ako se preda niz primitivnih tipova, a Popis od niz tog primitivnog tipa vraća se.

Na primjer:

int [] arr = {1, 2, 3, 4, 5}; Lista popisa = List.of (arr);

U ovom slučaju, a Popis veličine 1 vraća se i element s indeksom 0 sadrži niz.

3.2. Karta

Potpis Karta tvornička metoda je:

statička karta (K k1, V v1, K k2, V v2, K k3, V v3)

i upotreba:

Karta karte = Map.of ("foo", "a", "bar", "b", "baz", "c");

Slično kao Popis i Postavi, od(…) metoda je preopterećena da bi imala 0 do 10 parova ključ / vrijednost.

U slučaju Karta, postoji drugačija metoda za više od 10 parova ključ / vrijednost:

statička karta unosa (unosi Map.Entry ...)

i to je upotreba:

Map map = Map.ofEntries (new AbstractMap.SimpleEntry ("foo", "a"), new AbstractMap.SimpleEntry ("bar", "b"), new AbstractMap.SimpleEntry ("baz", "c"));

Prosljeđivanje dvostrukih vrijednosti za Key izbacilo bi IlegalArgumentException:

@Test (očekuje se = IllegalArgumentException.class) javna praznina givenDuplicateKeys_ifIllegalArgExp_thenSuccess () {Map.of ("foo", "a", "foo", "b"); }

Opet, u slučaju Karta previše su i primitivni tipovi u autoboxu.

4. Napomene o provedbi

Zbirke kreirane tvorničkim metodama nisu uobičajene implementacije.

Na primjer, Popis nije an ArrayList i Karta nije a HashMap. To su različite implementacije koje su uvedene u Javi 9. Te su implementacije interne i njihovi konstruktori imaju ograničen pristup.

U ovom ćemo odjeljku vidjeti neke važne razlike u implementaciji koje su zajedničke za sve tri vrste zbirki.

4.1. Nepromjenjiv

Zbirke stvorene tvorničkim metodama su nepromjenjive, a mijenjanje elementa, dodavanje novih elemenata ili uklanjanje elemenata baca UnsupportedOperationException:

@Test (očekuje se = UnsupportedOperationException.class) javna praznina onElemAdd_ifUnSupportedOpExpnThrown_thenSuccess () {Set set = Set.of ("foo", "bar"); set.add ("baz"); }
@Test (očekuje se = UnsupportedOperationException.class) javna praznina onElemModify_ifUnSupportedOpExpnThrown_thenSuccess () {Lista popisa = Lista.of ("foo", "bar"); list.set (0, "baz"); } 

S druge strane, kolekcija se vratila iz Nizovi.asListje promjenjiv. Stoga je moguće promijeniti ili ukloniti postojeće elemente. Slično Popis, ne možemo dodati nove elemente na popis vraćen s Nizovi.asList.

@Test (očekuje se = UnsupportedOperationException.class) javna praznina onElemRemove_ifUnSupportedOpExpnThrown_thenSuccess () {Map map = Map.of ("foo", "a", "bar", "b"); map.remove ("foo"); }

4.2. Ne null Dopušteni element

U slučaju Popis i Postavi, nijedan element ne može biti null. U slučaju a Karta, niti ključevi niti vrijednosti ne mogu biti null. Pretjecanje null argument baca a NullPointerException:

@Test (očekuje se = NullPointerException.class) javna praznina onNullElem_ifNullPtrExpnThrown_thenSuccess () {List.of ("foo", "bar", null); }

Za razliku od Popis, Nizovi.asList metoda prihvaća null vrijednosti.

4.3. Primjeri temeljeni na vrijednosti

Primjerci stvoreni tvorničkim metodama temelje se na vrijednosti. To znači da tvornice mogu slobodno stvoriti novu instancu ili vratiti postojeću instancu.

Stoga, ako kreiramo Popise s istim vrijednostima, oni se mogu ili ne moraju odnositi na isti objekt na hrpi:

Popis list1 = List.of ("foo", "bar"); Lista list2 = List.of ("foo", "bar");

U ovom slučaju, popis1 == popis2 može ili ne mora procijeniti na pravi ovisno o JVM-u.

4.4. Serijalizacija

Zbirke stvorene tvorničkim metodama su Serijalizirati ako su elementi zbirke Serijalizirati.

5. Zaključak

U ovom smo članku predstavili nove tvorničke metode za zbirke predstavljene u Javi 9.

Zaključili smo zašto je ova značajka dobrodošla promjena preispitivanjem nekih prošlih metoda za stvaranje neizmijenjivih kolekcija. Pokrili smo njegovu upotrebu i istaknuli ključne točke koje treba uzeti u obzir tijekom njihove upotrebe.

Na kraju smo pojasnili da se ove zbirke razlikuju od uobičajenih implementacija i ukazali na ključne razlike.

Cjeloviti testovi izvornog koda i jedinice za ovaj članak dostupni su na GitHubu.


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