Initialisering av Java-liste i en linje

1. Introduksjon

I denne raske opplæringen vil vi undersøke hvordan vi kan initialisere en Liste ved hjelp av en-liners.

2. Lag fra en matrise

Vi kan lage en Liste fra en matrise og takket være matrikelbokstaver kan vi initialisere dem i en linje:

Listeliste = Arrays.asList (ny streng [] {"foo", "bar"});

Vi kan stole på varargsmekanismen for å håndtere opprettelsen av matrisen. På den måten kan vi skrive mer kortfattet og lesbar kode:

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

Resultatforekomsten av denne koden implementerer Liste grensesnitt, men det er ikke et java.util.ArrayList ei heller LinkedList. I stedet er det en Liste støttet av den opprinnelige matrisen som har to implikasjoner.

Selv om klassenavnet tilfeldigvis er ArrayList men i java.util.Arrayer pakke.

2.1. Fast størrelse

Resultatinstansen fra Arrays.asList vil ha en fast størrelse:

@Test (forventet = UnsupportedOperationException.class) offentlig ugyldig givenArraysAsList_whenAdd_thenUnsupportedException () {List list = Arrays.asList ("foo", "bar"); list.add ("baz"); }

2.2. Delt referanse

Den originale matrisen og listen deler de samme referansene til objektene:

@Test offentlig ugyldighet givenArraysAsList_whenCreated_thenShareReference () {String [] array = {"foo", "bar"}; Listeliste = Arrays.asList (matrise); array [0] = "baz"; assertEquals ("baz", list.get (0)); }

3. Opprett fra en strøm (Java 8)

Vi kan enkelt konvertere en Strøm inn i alle slags Samling.

Derfor med fabrikkmetodene for Strømmer, kan vi opprette og initialisere lister i en linje:

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

Vi bør merke det her Collectors.toList () garanterer ikke den nøyaktige implementeringen av den returnerte Liste.

Det er ingen generell kontrakt om mutabilitet, serialiserbarhet eller trådsikkerhet for den returnerte forekomsten. Derfor bør ikke koden vår stole på noen av disse egenskapene.

Noen kilder fremhever det Stream.of (…) .collect (…) kan ha større minne og ytelsesavtrykk enn Arrays.asList () men i nesten alle tilfeller er det en slik mikrooptimalisering at det er liten forskjell.

4. Fabrikkmetoder (Java 9)

I JDK 9 har flere praktiske fabrikkmetoder blitt introdusert for samlinger:

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

En viktig detalj er at de returnerte forekomster er uforanderlige. Utover det har fabrikkmetodene flere fordeler innen plasseffektivitet og trådsikkerhet.

Dette emnet blir utforsket mer i denne artikkelen.

5. Initialisering med dobbelt stag

Flere steder kan vi finne en metode som kalles 'Initialisering med dobbel stag' som ser ut som:

@Test offentlig ugyldig givenAnonymousInnerClass_thenInitialiseList () {List cities = new ArrayList () {{add ("New York"); legg til ("Rio"); legg til ("Tokyo"); }}; assertTrue (towns.contains ("New York")); }

Navnet 'Initialisering med dobbel stag' er ganske misvisende. Syntaksen kan se kompakt og elegant ut, men den skjuler farlig det som går under panseret.

Det er faktisk ikke en ‘Dobbel stag’ syntakselement i Java, det er to blokker formatert med vilje på denne måten.

Med de ytre selene, erklærer vi en anonym indre klasse som vil være en underklasse av ArrayList. Inne i disse tannreguleringene kan vi erklære detaljene i underklassen vår.

Som vanlig kan vi bruke forekomst initialiseringsblokker, og det er her det indre paret av bukseseler kommer fra.

Kortfattet av denne syntaksen er fristende, men det regnes som et antimønster.

For å lese mer om initialisering med dobbel stag, ta en titt på artikkelen vår her.

6. Konklusjon

Moderne Java tilbyr flere alternativer for å lage en Samling i en linje. Metoden vi valgte er nesten helt nede på personlig preferanse, snarere enn teknisk resonnement.

En viktig takeaway er at selv om det ser grasiøst ut, antimønsteret for anonym indre klasseinitialisering (aka 'double brace') har mange negative bivirkninger.

Som alltid er koden tilgjengelig på GitHub.


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