Inicializácia zoznamu Java v jednom riadku

1. Úvod

V tomto rýchlom výučbe preskúmame, ako môžeme inicializovať a Zoznam pomocou jednoradových vložiek.

2. Vytvorte z poľa

Môžeme vytvoriť Zoznam z poľa a vďaka literálom poľa ich môžeme inicializovať do jedného riadku:

List list = Arrays.asList (nový reťazec [] {"foo", "bar"});

Môžeme dôverovať varargsovmu mechanizmu, aby zvládol vytvorenie poľa. Takto môžeme napísať stručnejší a čitateľnejší kód:

@Test public void givenArraysAsList_thenInitialiseList () {List list = Arrays.asList ("foo", "bar"); assertTrue (list.contains ("foo")); }

Výsledná inštancia tohto kódu implementuje Zoznam rozhranie, ale nie je to java.util.ArrayList ani a LinkedList. Namiesto toho je to Zoznam kryté pôvodným poľom, ktoré má dva dôsledky.

Názov triedy sa však náhodou volá ArrayList ale v java.util.Arrays balíček.

2.1. Pevná veľkosť

Výsledná inštancia z Arrays.asList bude mať pevnú veľkosť:

@Test (očakáva sa = UnsupportedOperationException.class) public void givenArraysAsList_whenAdd_thenUnsupportedException () {List list = Arrays.asList ("foo", "bar"); list.add ("baz"); }

2.2. Zdieľaný odkaz

Pôvodné pole a zoznam zdieľajú rovnaké odkazy na objekty:

@Test public void givenArraysAsList_whenCreated_thenShareReference () {String [] pole = {"foo", "bar"}; Zoznam zoznam = Arrays.asList (pole); pole [0] = "baz"; assertEquals ("baz", list.get (0)); }

3. Tvorba zo streamu (Java 8)

Môžeme ľahko previesť Prúd do akéhokoľvek druhu Zbierka.

Preto s továrenskými metódami pre Prúdy, môžeme vytvárať a inicializovať zoznamy v jednom riadku:

@Test public void givenStream_thenInitializeList () {List list = Stream.of ("foo", "bar") .collect (Collectors.toList ()); assertTrue (list.contains ("foo")); }

Mali by sme to tu označiť Collectors.toList () nezaručuje presnú implementáciu vrátených Zoznam.

Neexistuje žiadny všeobecný kontrakt o premenlivosti, serializovateľnosti alebo bezpečnosti vlákien vrátenej inštancie. Náš kód by sa preto nemal spoliehať na žiadnu z týchto vlastností.

Niektoré zdroje to zdôrazňujú Stream.of (…) .collect (…) môže mať väčšiu pamäť a výkon, ako Arrays.asList () ale takmer vo všetkých prípadoch je to taká mikrooptimalizácia, že je malý rozdiel.

4. Továrne metódy (Java 9)

V JDK 9 bolo zavedených niekoľko pohodlných továrenských metód pre zbierky:

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

Jedným dôležitým detailom je, že vrátené inštancie sú nemenné. Okrem toho majú továrenské metódy niekoľko výhod v efektívnosti priestoru a bezpečnosti vlákien.

Tejto téme sa viac venuje tento článok.

5. Inicializácia dvojitej zátvorky

Na viacerých miestach nájdeme metódu tzv „Dvojitá inicializácia zátvorky“ ktorý vyzerá ako:

@Test public void givenAnonymousInnerClass_thenInitialiseList () {Zoznam miest = nový ArrayList () {{add ("New York"); pridať („Rio“); pridať („Tokio“); }}; assertTrue (city.contains ("New York")); }

Názov „Dvojitá inicializácia zátvorky“ je dosť zavádzajúce. Syntax môže pôsobiť kompaktne a elegantne, ale nebezpečne skrýva to, čo sa deje pod kapotou.

V skutočnosti neexistuje „Dvojitá zátvorka“ syntaxový prvok v Jave, to sú dva bloky takto naformátované zámerne.

Pomocou vonkajších zložených zátvoriek deklarujeme anonymnú vnútornú triedu, ktorá bude podtriedou ArrayList. Vo vnútri týchto zátvoriek môžeme deklarovať podrobnosti o našej podtriede.

Ako obvykle, môžeme použiť bloky inicializátora inštancií a odtiaľ pochádza vnútorná dvojica zložených zátvoriek.

Stručnosť tejto syntaxe je lákavá, je však považovaná za anti-vzor.

Ak sa chcete dozvedieť viac informácií o inicializácii dvojitých zátvoriek, pozrite si náš článok tu.

6. Záver

Moderná Java ponúka niekoľko možností na vytvorenie Zbierka v jednom riadku. Metóda, ktorú sme si vybrali, je takmer výlučne na osobných preferenciách, a nie na technických dôvodoch.

Dôležitým spôsobom je, že hoci to vyzerá elegantne, anti-vzor anonymnej inicializácie vnútornej triedy (alias „dvojitá zátvorka“) má veľa negatívnych vedľajších účinkov.

Ako vždy, kód je k dispozícii na GitHub.


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