Java Convenience Factory Metódy pre zbierky

1. Prehľad

Java 9 prináša dlho očakávaný syntaktický cukor na vytváranie malých neupraviteľných Zbierka inštancie pomocou stručného kódu s jednoduchým riadkom. Podľa JEP 269 budú do JDK 9 zahrnuté nové spôsoby výroby z výroby.

V tomto článku sa budeme venovať jeho použitiu spolu s podrobnosťami implementácie.

2. História a motivácia

Vytvorenie malého nemenného Zbierka v Jave je veľmi podrobný, a to tradičným spôsobom.

Zoberme si príklad a Nastaviť:

Set set = new HashSet (); set.add ("foo"); set.add ("lišta"); set.add ("baz"); set = Collections.unmodifiableSet (sada);

To je príliš veľa kódu na jednoduchú úlohu a malo by byť možné vykonať ho jediným výrazom.

Vyššie uvedené platí aj pre a Mapa.

Avšak pre Zoznam, existuje továrenská metóda:

Zoznam list = Arrays.asList ("foo", "bar", "baz");

Aj keď toto Zoznam tvorba je lepšia ako inicializácia konštruktora, je to menej zrejmé, pretože bežnou intuíciou by nebolo hľadanie Polia trieda pre metódy na vytvorenie a Zoznam:

Existujú aj iné spôsoby zníženia výrečnosti, ako napríklad dvojitá zátvorka technika:

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

alebo pomocou Java 8 Prúdy:

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

Technika dvojitej zátvorky je iba o niečo menej verbálna, ale výrazne znižuje čitateľnosť (a je považovaná za anti-vzor).

Verzia Java 8 je však jednoriadkový výraz a tiež má určité problémy. Po prvé, nie je to zrejmé a intuitívne. Po druhé, stále je to podrobné. Po tretie, zahŕňa vytváranie nepotrebných objektov. A po štvrté, túto metódu nemožno použiť na vytvorenie a Mapa.

Aby sme zhrnuli nedostatky, žiadny z vyššie uvedených prístupov nespracováva konkrétny prípad použitia a vytvára malú neupraviteľnú položku Zbierka prvotriedny problém.

3. Popis a použitie

Boli stanovené statické metódy Zoznam, Nastaviťa Mapa rozhrania, ktoré berú prvky ako argumenty a vracajú inštanciu Zoznam, Nastaviťa Mapa, resp.

Táto metóda je pomenovaná z (...) pre všetky tri rozhrania.

3.1. Zoznam a Nastaviť

Podpis a vlastnosti Zoznam a Nastaviť továrenské metódy sú rovnaké:

statický zoznam (E e1, E e2, E e3) statickej sady (E e1, E e2, E e3)

použitie metód:

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

Ako vidíme, je to veľmi jednoduché, krátke a výstižné.

V príklade sme použili metódu s, ktorá berie ako parametre presne tri prvky a vráti a Zoznam / Nastaviť o veľkosti 3.

Existuje však 12 preťažených verzií tejto metódy - jedenásť s 0 až 10 parametrami a jedna s var-args:

static List of () static List of (E e1) static List of (E e1, E e2) // .... and so on static List of (E ... elems)

Z praktických dôvodov by stačilo 10 prvkov, ale ak je potrebných viac, je možné použiť verziu var-args.

Teraz sa môžeme spýtať, aký má zmysel mať 11 ďalších metód, ak existuje verzia var-args, ktorá dokáže pracovať s ľubovoľným počtom prvkov.

Odpoveďou na to je výkon. Každé volanie metódy var-args implicitne vytvára pole. Vďaka preťaženým metódam sa zabráni zbytočnému vytváraniu objektov a ich réžii pri odstraňovaní odpadu. Naopak, Arrays.asList vždy vytvorí toto implicitné pole a v dôsledku toho je menej efektívne, keď je počet prvkov nízky.

Pri vzniku a Nastaviť pomocou továrenskej metódy, ak sa ako parametre odovzdajú duplicitné prvky, potom IllegalArgumentException je vyhodený za behu:

@Test (očakáva sa = IllegalArgumentException.class) public void onDuplicateElem_IfIllegalArgExp_thenSuccess () {Set.of ("foo", "bar", "baz", "foo"); }

Je potrebné si tu uvedomiť, že keďže továrenské metódy používajú generické typy, primitívne typy sa autoboxujú.

Ak je odovzdané pole primitívneho typu, a Zoznam z pole tohto primitívneho typu sa vráti.

Napríklad:

int [] arr = {1, 2, 3, 4, 5}; Zoznam zoznam = Zoznam (arr);

V takom prípade a Zoznam vráti sa veľkosť 1 a prvok v indexe 0 obsahuje pole.

3.2. Mapa

Podpis Mapa továrenská metóda je:

statická mapa (K k1, V v1, K k2, V v2, K k3, V v3)

a použitie:

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

Podobne ako Zoznam a Nastaviť, z (...) metóda je preťažená, aby mala 0 až 10 párov kľúč - hodnota.

V prípade Mapa, pre viac ako 10 párov kľúč - hodnota existuje iná metóda:

statická mapa vstupov (položky záznamu. vstup ...)

a jeho použitie:

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

Predanie duplicitných hodnôt pre Key by vyvolalo znak IllegalArgumentException:

@Test (očakáva sa = IllegalArgumentException.class) public void givenDuplicateKeys_ifIllegalArgExp_thenSuccess () {Map.of ("foo", "a", "foo", "b"); }

Opäť v prípade Mapa primitívne typy sú tiež autoboxované.

4. Poznámky k implementácii

Kolekcie vytvorené pomocou továrenských metód nie sú bežne používanými implementáciami.

Napríklad Zoznam nie je ArrayList a Mapa nie je HashMap. Jedná sa o rôzne implementácie, ktoré sú zavedené v prostredí Java 9. Tieto implementácie sú interné a ich konštruktory majú obmedzený prístup.

V tejto časti uvidíme niektoré dôležité implementačné rozdiely, ktoré sú spoločné pre všetky tri typy kolekcií.

4.1. Nezmeniteľné

Kolekcie vytvorené pomocou továrenských metód sú nemenné a zmena prvku, pridanie nových prvkov alebo odstránenie prvku vyvolá vrh UnsupportedOperationException:

@Test (očakáva sa = UnsupportedOperationException.class) public void onElemAdd_ifUnSupportedOpExpnThrown_thenSuccess () {Set set = Set.of ("foo", "bar"); set.add ("baz"); }
@Test (expect = UnsupportedOperationException.class) public void onElemModify_ifUnSupportedOpExpnThrown_thenSuccess () {List list = List.of ("foo", "bar"); list.set (0, "baz"); } 

Na druhej strane sa zbierka vrátila z Arrays.asListje premenlivý. Preto je možné existujúce prvky zmeniť alebo odstrániť. Podobný Zoznam, nemôžeme pridávať nové prvky do zoznamu vráteného z Arrays.asList.

@Test (expect = UnsupportedOperationException.class) public void onElemRemove_ifUnSupportedOpExpnThrown_thenSuccess () {Map map = Map.of ("foo", "a", "bar", "b"); map.remove ("foo"); }

4.2. Nie nulový Element povolený

V prípade Zoznam a Nastaviť, nemôžu byť žiadne prvky nulový. V prípade a Mapa, nemôžu byť ani kľúče, ani hodnoty nulový. Prihrávka nulový hádka hádže a NullPointerException:

@Test (očakáva sa = NullPointerException.class) public void onNullElem_ifNullPtrExpnThrown_thenSuccess () {List.of ("foo", "bar", null); }

Na rozdiel od Zoznam, Arrays.asList metóda akceptuje nulový hodnoty.

4.3. Hodnotové inštancie

Inštancie vytvorené továrenskými metódami sú založené na hodnotách. To znamená, že továrne môžu vytvoriť novú inštanciu alebo vrátiť existujúcu inštanciu.

Ak teda vytvoríme Zoznamy s rovnakými hodnotami, môžu alebo nemusia odkazovať na rovnaký objekt na halde:

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

V tomto prípade, zoznam1 == zoznam2 môže alebo nemusí hodnotiť do pravda v závislosti od JVM.

4.4. Serializácia

Zbierky vytvorené továrenskými metódami sú Serializovateľné ak sú prvky zbierky Serializovateľné.

5. Záver

V tomto článku sme predstavili nové továrenské metódy pre kolekcie zavedené v prostredí Java 9.

Dospeli sme k záveru, prečo je táto funkcia vítanou zmenou, keď sme prešli cez niektoré minulé metódy vytvárania nemodifikovateľných zbierok. Pokryli sme jeho využitie a zdôraznili kľúčové body, ktoré je potrebné pri ich používaní zohľadniť.

Na záver sme objasnili, že tieto kolekcie sa líšia od bežne používaných implementácií, a poukázali na kľúčové rozdiely.

Kompletné zdrojové kódy a testy jednotiek pre tento článok sú k dispozícii na GitHub.


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