Collecter un flux Java vers une collection immuable

Recueillir un flux Java dans une collection immuable

1. introduction

Dans cet article rapide, nous allons examiner différentes manières de collecter desStreams Java vers desCollections – immuables qui nécessitent une approche spéciale car lesCollectorstandard ne fonctionnent qu'avec des structures de données mutables.

2. Dépendance Maven

Nous allons utiliser la bibliothèque Guava de Google pour piloter certains de nos exemples:


    com.google.guava
    guava
    22.0

Nous pouvons obtenir la dernière version de cette dépendance à partir dehere.

3. Utilisation descollectingAndThen() de Java

La méthodecollectingAndThen() de la classeCollectors de Java accepte unCollector et unfinisherFunction qui est appliqué au résultat renvoyé par lesCollector:

@Test
public void whenUsingCollectingToImmutableList_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c");
    List result = givenList.stream()
      .collect(collectingAndThen(toList(), ImmutableList::copyOf));

    System.out.println(result.getClass());
}

Puisque nous ne pouvons pas utiliser la toCollection() Collector directement,, nous devons collecter des éléments dans une liste temporaire, puis en construire une liste immuable.

Dans cet exemple, nous convertissons unStream en unList à l'aide du collecteurtoList(), puis créons unImmutableList. LeImmutableList fait partie de la bibliothèque Guava. Si nous enregistrons la sortie dans la console, nous obtiendrons la classe du sous-jacent

Si nous enregistrons la sortie dans la console, nous obtiendrons la classe de l'implémentation sous-jacente deList:

class com.google.common.collect.RegularImmutableList

4. Utilisation desCollectors de Guava

À partir de Guava 21, chaque classe immuable s'accompagne d'unCollector qui est aussi facile à utiliser que lesCollectors: standard

@Test
public void whenCollectToImmutableList_thenSuccess() {
    List list = IntStream.range(0, 9)
      .boxed()
      .collect(ImmutableList.toImmutableList());
}

L'instance résultante est leRegularImmutableList:

class com.google.common.collect.RegularImmutableList

5. Créer un collecteur personnalisé

Maintenant, allons plus loin et implémentons nosCollector personnalisés. Pour atteindre cet objectif, nous allons utiliser la méthode statiqueCollector.of():

public static  Collector, List> toImmutableList() {
    return Collector.of(ArrayList::new, List::add,
    (left, right) -> {
      left.addAll(right);
      return left;
    }, Collections::unmodifiableList);
}

Pour en savoir plus sur l'implémentation deCollectors personnalisés, veuillez consulter la section 4 dethis article. Et c'est tout. La méthode ci-dessus fait partie de notre classe personnalisée

Nous pouvons l'utiliser maintenant comme n'importe quel autreCollectors intégré:

@Test
public void whenCollectToMyImmutableListCollector_thenSuccess() {
    List givenList = Arrays.asList("a", "b", "c", "d");
    List result = givenList.stream()
      .collect(MyImmutableListCollector.toImmutableList());
}

Enfin, vérifions le résultat:

class java.util.Collections$UnmodifiableRandomAccessList