Java Convenience Factory módszerek a gyűjteményekhez

1. Áttekintés

A Java 9 hozza meg a régóta várt szintaktikai cukrot a kis, módosíthatatlan létrehozáshoz Gyűjtemény tömör kódú egysoros vonalat használó példányok. A JEP 269 szerint a JDK 9 új kényelmi gyári módszereket tartalmaz.

Ebben a cikkben a használatával és a megvalósítás részleteivel foglalkozunk.

2. Történelem és motiváció

Létrehozása egy kis változhatatlan Gyűjtemény a Java-ban nagyon részletes a hagyományos módon.

Vegyünk egy példát a Készlet:

Set set = new HashSet (); set.add ("foo"); set.add ("bár"); set.add ("baz"); set = Gyűjtemények.unmodifiableSet (halmaz);

Ez túl sok kód egy egyszerű feladathoz, és lehetővé kell tenni, hogy egyetlen kifejezésben hajtsa végre.

A fentiek igazak a Térkép.

Azonban azért Lista, van egy gyári módszer:

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

Bár ez Lista a létrehozás jobb, mint a konstruktor inicializálása, ez kevésbé nyilvánvaló, mivel a közös megérzés nem az lenne, hogy utánanézzünk Tömbök osztály az a létrehozásának módszereihez Lista:

A bőbeszédűség csökkentésére más módszerek is vannak, mint például a kettős merevítő inicializálás technika:

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

vagy a Java 8 használatával Patakok:

Stream.of ("foo", "bar", "baz") .collect (collectAndThen (toSet (), Gyűjtemények :: unmodifiableSet));

A kettős merevítő technika csak egy kicsit kevésbé bőbeszédű, de nagymértékben csökkenti az olvashatóságot (és anti-mintának számít).

A Java 8 verzió azonban egysoros kifejezés, és van néhány problémája is. Először is, ez nem nyilvánvaló és intuitív. Másodszor, még mindig bőbeszédű. Harmadszor felesleges tárgyak létrehozásával jár. Negyedszer, ez a módszer nem használható a Térkép.

Összefoglalva a hiányosságokat, a fenti megközelítések egyike sem kezeli a konkrét felhasználási esetet, ami kis módosíthatatlanságot hoz létre Gyűjtemény első osztályú probléma.

3. Leírás és használat

Statikus módszereket biztosítottak Lista, Készlet, és Térkép olyan interfészek, amelyek az elemeket argumentumként veszik fel, és a Lista, Készlet, és Térképill.

Ezt a módszert nevezik meg nak,-nek(…) mindhárom interfész esetében.

3.1. Lista és Készlet

A. Aláírása és jellemzői Lista és Készlet a gyári módszerek ugyanazok:

(E e1, E e2, E e3) statikus listája (E e1, E e2, E e3)

a módszerek használata:

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

Mint láthatjuk, nagyon egyszerű, rövid és tömör.

A példában a metódust használtuk azzal, hogy pontosan három elemet vesz fel paraméterként, és a-t ad vissza Lista / Készlet 3. méretű.

De ennek a módszernek 12 túlterhelt verziója van - tizenegy 0-10 paraméterrel és egy var-args-szal:

statikus () statikus lista (E e1) statikus lista (E e1, E e2) // .... és így tovább statikus (E ... elem) lista

A legtöbb gyakorlati célból 10 elem elegendő lenne, de ha többre van szükség, akkor a var-args verzió használható.

Most megkérdezhetjük, hogy mi értelme van 11 extra metódusnak, ha van egy var-args verzió, amely tetszőleges számú elemre képes.

A válasz erre a teljesítmény. Minden var-args metódushívás implicit módon létrehoz egy tömböt. A túlterhelt módszerekkel elkerülhető a felesleges tárgyalkotás és annak szemétszedési költségei. Ellenkezőleg, Tömbök.asList mindig létrehozza ezt az implicit tömböt, következésképpen kevésbé hatékony, ha az elemek száma alacsony.

Létrehozása során a Készlet gyári módszerrel, ha ismétlődő elemeket adunk át paraméterként, akkor IllegalArgumentException futás közben dobják:

@Test (várható = IllegalArgumentException.class) public void onDuplicateElem_IfIllegalArgExp_thenSuccess () {Set.of ("foo", "bar", "baz", "foo"); }

Fontos megjegyezni itt, hogy mivel a gyári módszerek generikumokat használnak, a primitív típusok autoboxálódnak.

Ha primitív tömböt adunk át, a Lista nak,-nek sor az a primitív típus visszatér.

Például:

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

Ebben az esetben a Lista az 1-es méretet adja vissza, és a 0 indexben lévő elem tartalmazza a tömböt.

3.2. Térkép

Aláírása Térkép gyári módszer:

(K k1, V v1, K k2, V v2, K k3, V v3 statikus térképe)

és a használat:

Térképtérkép = Map.of ("foo", "a", "bár", "b", "baz", "c");

Hasonlóan Lista és Készlet, a nak,-nek(…) A módszer túlterhelt, hogy 0-10 kulcs-érték pár legyen.

Abban az esetben Térkép, van egy másik módszer több mint 10 kulcs-érték párra:

statikus belépési térkép (térkép. bejegyzés ... bejegyzések)

és a használata:

Map map = Map.ofEntries (új AbstractMap.SimpleEntry ("foo", "a"), új AbstractMap.SimpleEntry ("bár", "b"), új AbstractMap.SimpleEntry ("baz", "c"));

A Key duplikált értékeinek megadása egy IllegalArgumentException:

@Test (várható = IllegalArgumentException.class) public void givenDuplicateKeys_ifIllegalArgExp_thenSuccess () {Map.of ("foo", "a", "foo", "b"); }

Ismét a Térkép a primitív típusok is autoboxok.

4. Megvalósítási megjegyzések

A gyári módszerekkel létrehozott gyűjtemények nem általánosan használt implementációk.

Például a Lista nem egy Tömb lista és a Térkép nem egy HashMap. Ezek különböző megvalósítások, amelyeket a Java 9 vezet be. Ezek a megvalósítások belsőek, és a kivitelezők korlátozott hozzáféréssel rendelkeznek.

Ebben a szakaszban néhány fontos megvalósítási különbséget fogunk látni, amelyek mind a három típusú gyűjteményben közösek.

4.1. Változhatatlan

A gyári módszerekkel létrehozott gyűjtemények megváltoztathatatlanok, és elem módosítása, új elemek hozzáadása vagy egy elem dobásának eltávolítása UnsupportedOperationException:

@Test (várható = UnsupportedOperationException.class) public void onElemAdd_ifUnSupportedOpExpnThrown_thenSuccess () {Set set = Set.of ("foo", "bar"); set.add ("baz"); }
@Test (várható = UnsupportedOperationException.class) public void onElemModify_ifUnSupportedOpExpnThrown_thenSuccess () {List list = List.of ("foo", "bar"); list.set (0, "baz"); } 

Viszont a gyűjtemény visszatért Tömbök.asListmegváltoztatható. Ezért lehetséges a meglévő elemek módosítása vagy eltávolítása. Hasonló Listája, nem adhatunk hozzá új elemeket a listából, ahonnan visszaküldtük Tömbök.asList.

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

4.2. Nem nulla Elem megengedett

Abban az esetben Lista és Készlet, egyetlen elem sem lehet nulla. Abban az esetben, ha a Térkép, sem kulcsok, sem értékek nem lehetnek nulla. Elhaladó nulla érv dob a NullPointerException:

@Test (várható = NullPointerException.class) public void onNullElem_ifNullPtrExpnThrown_thenSuccess () {List.of ("foo", "bar", null); }

Szemben a Listája, a Tömbök.asList módszer elfogadja nulla értékek.

4.3. Értékalapú példányok

A gyári módszerekkel létrehozott példányok értékalapúak. Ez azt jelenti, hogy a gyárak szabadon létrehozhatnak új példányt, vagy visszaadhatnak egy meglévő példányt.

Ezért, ha azonos értékű listákat hozunk létre, akkor hivatkozhatnak ugyanarra az objektumra a kupacban:

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

Ebben az esetben, list1 == list2 értékelheti vagy nem értékelheti igaz a JVM-től függően.

4.4. Serializálás

A gyári módszerekkel létrehozott gyűjtemények Sorosítható ha a gyűjtemény elemei Sorosítható.

5. Következtetés

Ebben a cikkben bemutattuk a Java 9-ben bevezetett új gyári módszereket a Gyűjtemények számára.

Arra a következtetésre jutottunk, hogy ez a szolgáltatás miért örvendetes változás, áttekintve a módosíthatatlan gyűjtemények létrehozásának néhány korábbi módszerét. Kitértünk a használatára, és kiemeltük azokat a legfontosabb szempontokat, amelyeket figyelembe kell venni azok használata során.

Végül tisztáztuk, hogy ezek a gyűjtemények eltérnek a gyakran használt megvalósításoktól, és rámutattunk a legfontosabb különbségekre.

A cikk teljes forráskódja és egységtesztjei elérhetők a GitHubon.


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