Initialisation de la liste Java en une seule ligne

1. Introduction

Dans ce tutoriel rapide, nous allons étudier comment initialiser une liste à l' aide de one-liners.

2. Créer à partir d'un tableau

Nous pouvons créer une liste à partir d'un tableau et grâce aux littéraux de tableau, nous pouvons les initialiser en une seule ligne:

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

Nous pouvons faire confiance au mécanisme varargs pour gérer la création du tableau. Par cela, nous pouvons écrire un code plus concis et lisible:

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

L'instance de résultat de ce code implémente l' interface List mais ce n'est pas une java.util.ArrayList ni une LinkedList . Au lieu de cela, il s'agit d'une liste sauvegardée par le tableau d'origine qui a deux implications.

Bien que le nom de la classe soit ArrayList, mais dans le package java.util.Arrays .

2.1. Taille fixe

L'instance de résultat de Arrays.asList aura une taille fixe:

@Test(expected = UnsupportedOperationException.class) public void givenArraysAsList_whenAdd_thenUnsupportedException() { List list = Arrays.asList("foo", "bar"); list.add("baz"); }

2.2. Référence partagée

Le tableau d'origine et la liste partagent les mêmes références aux objets:

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

3. Créer à partir d'un flux (Java 8)

Nous pouvons facilement convertir un Stream en n'importe quel type de Collection.

Par conséquent, avec les méthodes d'usine pour Streams , nous pouvons créer et initialiser des listes en une seule ligne:

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

Nous devons marquer ici que Collectors.toList () ne garantit pas l'implémentation exacte de la List retournée .

Il n'y a pas de contrat général sur la mutabilité, la sérialisabilité ou la sécurité des threads de l'instance retournée. Par conséquent, notre code ne doit s'appuyer sur aucune de ces propriétés.

Certaines sources soulignent que Stream.of (…) .collect (…) peut avoir une plus grande capacité de mémoire et de performances que Arrays.asList () mais dans presque tous les cas, c'est une telle micro-optimisation qu'il y a peu de différence.

4. Méthodes d'usine (Java 9)

Dans JDK 9, plusieurs méthodes d'usine pratiques ont été introduites pour les collections:

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

Un détail important est que les instances renvoyées sont immuables . Au-delà de cela, les méthodes d'usine présentent plusieurs avantages en termes d'efficacité spatiale et de sécurité des fils.

Ce sujet est exploré plus en détail dans cet article.

5. Initialisation à double accolade

À plusieurs endroits, nous pouvons trouver une méthode appelée `` initialisation à double accolade '' qui ressemble à:

@Test public void givenAnonymousInnerClass_thenInitialiseList() { List cities = new ArrayList() {{ add("New York"); add("Rio"); add("Tokyo"); }}; assertTrue(cities.contains("New York")); }

Le nom «initialisation à double accolade» est assez trompeur. La syntaxe peut paraître compacte et élégante, mais elle cache dangereusement ce qui se passe sous le capot.

Il n'y a pas réellement d' élément de syntaxe "double accolade" en Java, ce sont deux blocs formatés intentionnellement de cette façon.

Avec les accolades externes, nous déclarons une classe interne anonyme qui sera une sous-classe de ArrayList . À l'intérieur de ces accolades, nous pouvons déclarer les détails de notre sous-classe.

Comme d'habitude, nous pouvons utiliser des blocs d'initialisation d'instance et c'est de là que vient la paire intérieure d'accolades.

La brièveté de cette syntaxe est tentante mais elle est considérée comme un anti-pattern.

Pour en savoir plus sur l'initialisation à double accolade, consultez notre article ici.

6. Conclusion

Modern Java propose plusieurs options pour créer une collection en une seule ligne. La méthode que nous avons choisie est presque entièrement due à des préférences personnelles, plutôt qu'à un raisonnement technique.

Un point important à retenir est que, bien qu'il ait l'air élégant, l'anti-modèle d'initialisation de classe interne anonyme (alias «double accolade») a de nombreux effets secondaires négatifs .

Comme toujours, le code est disponible sur sur GitHub.