Initialisatie van Java-lijst in één regel

1. Inleiding

In deze korte tutorial onderzoeken we hoe we een Lijst met behulp van oneliners.

2. Maak van een array

We kunnen een Lijst vanuit een array en dankzij array-literals kunnen we ze op één regel initialiseren:

List list = Arrays.asList (nieuwe String [] {"foo", "bar"});

We kunnen het varargs-mechanisme vertrouwen om het maken van de array af te handelen. Daardoor kunnen we beknoptere en leesbare code schrijven:

@Test openbare ongeldig gegevenArraysAsList_thenInitialiseList () {List list = Arrays.asList ("foo", "bar"); assertTrue (list.contains ("foo")); }

Het resultaatinstantie van deze code implementeert de Lijst interface, maar het is geen java.util.ArrayList noch een LinkedList. In plaats daarvan is het een Lijst ondersteund door de originele array die twee implicaties heeft.

Hoewel de naam van de klas toevallig is ArrayList maar in de java.util.Arrays pakket.

2.1. Vaste maat

De resultaatinstantie van Arrays.asList zal een vaste maat hebben:

@Test (verwacht = UnsupportedOperationException.class) openbare ongeldige gegevenArraysAsList_whenAdd_thenUnsupportedException () {List list = Arrays.asList ("foo", "bar"); list.add ("baz"); }

2.2. Gedeelde referentie

De originele array en de lijst delen dezelfde verwijzingen naar de objecten:

@Test openbare ongeldig gegevenArraysAsList_whenCreated_thenShareReference () {String [] array = {"foo", "bar"}; Lijst lijst = Arrays.asList (array); array [0] = "baz"; assertEquals ("baz", list.get (0)); }

3. Maken vanuit een stream (Java 8)

We kunnen gemakkelijk een Stroom in elk soort Verzameling.

Daarom met de fabrieksmethoden voor Streamskunnen we lijsten op één regel maken en initialiseren:

@Test openbare leegte gegevenStream_thenInitializeList () {List list = Stream.of ("foo", "bar") .collect (Collectors.toList ()); assertTrue (list.contains ("foo")); }

Dat moeten we hier markeren Collectors.toList () garandeert niet de exacte uitvoering van het geretourneerde Lijst.

Er is geen algemeen contract over de veranderbaarheid, serialiseerbaarheid of thread-veiligheid van de geretourneerde instantie. Daarom mag onze code niet op een van deze eigenschappen vertrouwen.

Sommige bronnen benadrukken dat Stream.of (...) .collect (...) hebben mogelijk een groter geheugen en een grotere voetafdruk dan Arrays.asList () maar in bijna alle gevallen is het zo'n micro-optimalisatie dat er weinig verschil is.

4. Fabrieksmethoden (Java 9)

In JDK 9 zijn verschillende handige fabrieksmethoden geïntroduceerd voor collecties:

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

Een belangrijk detail is dat de geretourneerde exemplaren onveranderlijk zijn. Daarnaast hebben de fabrieksmethoden verschillende voordelen op het gebied van ruimte-efficiëntie en draadveiligheid.

Dit onderwerp wordt in dit artikel verder besproken.

5. Initialisatie met dubbele accolade

Op verschillende plaatsen kunnen we een methode vinden met de naam ‘Initialisatie met dubbele accolade ' die eruitziet als:

@Test openbare ongeldig gegevenAnonymousInnerClass_thenInitialiseList () {Lijst steden = nieuwe ArrayList () {{add ("New York"); add ("Rio"); add ("Tokyo"); }}; assertTrue (cities.contains ("New York")); }

De naam ‘Initialisatie met dubbele accolade ' is nogal misleidend. De syntaxis ziet er misschien compact en elegant uit, maar verbergt gevaarlijk wat er onder de motorkap gebeurt.

Er is eigenlijk geen 'Dubbele beugel' syntaxiselement in Java, dat zijn twee blokken die opzettelijk op deze manier zijn opgemaakt.

Met de buitenste accolades verklaren we een anonieme innerlijke klasse die een subklasse zal zijn van de ArrayList. Binnen deze beugels kunnen we de details van onze subklasse aangeven.

Zoals gewoonlijk kunnen we bijvoorbeeld initialisatieblokken gebruiken en dat is waar het binnenste paar beugels vandaan komt.

De beknoptheid van deze syntaxis is verleidelijk, maar het wordt als een antipatroon beschouwd.

Lees ons artikel hier voor meer informatie over initialisatie met dubbele beugel.

6. Conclusie

Modern Java biedt verschillende opties om een Verzameling op één regel. De methode die we hebben gekozen, is bijna volledig te wijten aan persoonlijke voorkeur, in plaats van technische redenering.

Een belangrijke afhaalmaaltijd is dat, hoewel het er gracieus uitziet, het antipatroon van anonieme initialisatie van de innerlijke klasse (ook bekend als 'dubbele beugel') heeft veel negatieve bijwerkingen.

Zoals altijd is de code beschikbaar op GitHub.