Initialisation de la liste Java sur une seule ligne

Initialisation de liste Java en une seule ligne

1. introduction

Dans ce rapide didacticiel, nous allons étudier comment initialiser unList à l'aide de one-liners.

Lectures complémentaires:

Collections.emptyList() vs. Nouvelle instance de liste

Découvrez les différences entre Collections.emptyList () et une nouvelle instance de liste.

Read more

Guide de la liste de tableaux Java

Guide rapide et pratique sur ArrayList en Java

Read more

2. Créer à partir d'un tableau

Nous pouvons créer unList à 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. De cette manière, nous pouvons écrire un code plus concis et lisible:

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

    assertTrue(list.contains("foo"));
}

The result instance of this code implements the List interface but it isn’t a java.util.ArrayList nor a LinkedList. Au lieu de cela, il s’agit d’unList soutenu par la baie d’origine, ce qui a deux implications.

Cependant, le nom de la classe se trouve êtreArrayList mais dans le packagejava.util.Arrays.

2.1. Taille fixe

L'instance de résultat deArrays.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)

On peut facilement convertir unStream en n'importe quel type deCollection.

Par conséquent, avec les méthodes d'usine pourStreams, 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 queCollectors.toList() ne garantit pas l'implémentation exacte desList renvoyés.

There’s no general contract about the mutability, serializability or thread-safety of the returned instance. Par conséquent, notre code ne doit reposer sur aucune de ces propriétés.

Certaines sources soulignent queStream.of(…).collect(…) peut avoir une plus grande capacité de mémoire et de performances queArrays.asList(), mais dans presque tous les cas, il s'agit d'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 pratiques en usine ont été introduites pour les collections:

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

One important detail is the returned instances are immutable. Au-delà, les méthodes d'usine présentent plusieurs avantages en termes de gain d'espace et de sécurité des fils.

Ce sujet est davantage exploré dansthis article.

5. Initialisation à double attache

A plusieurs endroits, nous pouvons trouver une méthode appelée‘double brace initialization' 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‘double brace initialization' 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’existe pas réellement d’élément de syntaxe‘double brace' en Java, ce sont deux blocs formatés intentionnellement de cette façon.

With the outer braces, we declare an anonymous inner class which will be a subclass of the 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 d'accolades interne.

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 articlehere.

6. Conclusion

Modern Java offers several options to create a Collection in one line. 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 que cela semble élégant,the anti-pattern of anonymous inner class initialization (a.k.a. ‘double brace') has many negative side-effects.

Comme toujours, le code est disponibleover on GitHub.