Initialisering af Java-liste i en linje

1. Introduktion

I denne hurtige vejledning undersøger vi, hvordan vi kan initialisere en Liste ved hjælp af en-liners.

2. Opret fra en matrix

Vi kan oprette en Liste fra en matrix og takket være matrixbogstaver kan vi initialisere dem i en linje:

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

Vi kan stole på varargsmekanismen til at håndtere arrayoprettelsen. Ved det kan vi skrive en mere kortfattet og læsbar kode:

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

Resultatet af denne kode implementerer Liste interface, men det er ikke en java.util.ArrayList ej heller en LinkedList. I stedet er det en Liste understøttet af den oprindelige matrix, som har to implikationer.

Selvom klassens navn tilfældigvis er ArrayList men i java.util.Arrays pakke.

2.1. Fast størrelse

Resultatinstansen fra Arrays.asList har en fast størrelse:

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

2.2. Delt reference

Den originale matrix og listen deler de samme referencer til objekterne:

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

3. Opret fra en stream (Java 8)

Vi kan let konvertere en Strøm ind i enhver form for Kollektion.

Derfor med fabriksmetoderne til Strømme, kan vi oprette og initialisere lister i en linje:

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

Vi skal her markere det Collectors.toList () garanterer ikke den nøjagtige implementering af den returnerede Liste.

Der er ingen generel kontrakt om mutabilitet, serialiserbarhed eller trådsikkerhed for den returnerede instans. Derfor skal vores kode ikke stole på nogen af ​​disse egenskaber.

Nogle kilder fremhæver det Stream.of (…) .collect (…) kan have større hukommelse og ydeevne fodaftryk end Arrays.asList () men i næsten alle tilfælde er det sådan en mikrooptimering, at der er lille forskel.

4. Fabriksmetoder (Java 9)

I JDK 9 er der indført flere praktiske fabriksmetoder til samlinger:

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

En vigtig detalje er, at de returnerede forekomster er uforanderlige. Derudover har fabriksmetoderne flere fordele inden for pladseffektivitet og trådsikkerhed.

Dette emne udforskes mere i denne artikel.

5. Initialisering med dobbelt brace

Flere steder kan vi finde en metode kaldet 'Dobbelt initialisering initialisering' der ligner:

@Test offentlig ugyldighed givenAnonymousInnerClass_thenInitialiseList () {Liste byer = ny ArrayList () {{tilføj ("New York"); tilføj ("Rio"); tilføj ("Tokyo"); }}; assertTrue (towns.contains ("New York")); }

Navnet 'Dobbelt initialisering initialisering' er ganske vildledende. Syntaksen kan se kompakt og elegant ud, men den skjuler farligt, hvad der går under emhætten.

Der er faktisk ikke en 'Dobbelt bøjle' syntakselement i Java, det er to blokke formateret bevidst på denne måde.

Med de ydre seler, erklærer vi en anonym indre klasse, som vil være en underklasse af ArrayList. Inde i disse seler kan vi erklære detaljerne i vores underklasse.

Som sædvanligt kan vi bruge instans-initialiseringsblokke, og det er her det indre par seler kommer fra.

Kortfattetheden af ​​denne syntaks er fristende, men det betragtes som et antimønster.

For at læse mere om initialisering med dobbeltstivere, se vores artikel her.

6. Konklusion

Moderne Java tilbyder flere muligheder for at oprette en Kollektion i en linje. Den metode, vi valgte, er næsten udelukkende afhængig af personlig præference snarere end teknisk ræsonnement.

En vigtig takeaway er, at selvom det ser yndefuld ud, anti-mønsteret af anonym indre klasseinitialisering (aka 'dobbelt stivhed') har mange negative bivirkninger.

Som altid er koden tilgængelig på GitHub.