Flux Java Null-Safe des collections

1. Vue d'ensemble

Dans ce didacticiel, nous verrons comment créer des flux de sécurité null à partir de collections Java.

Pour commencer, une certaine familiarité avec les références de méthode, les expressions Lambda, l' API facultative et Stream de Java 8 est nécessaire pour bien comprendre ce matériel.

Si vous n'êtes pas familier avec l'un de ces sujets, veuillez d'abord consulter nos articles précédents: Nouvelles fonctionnalités de Java 8, Guide de Java 8 facultatif et Introduction aux flux Java 8.

2. Dépendance de Maven

Avant de commencer, il y a une dépendance Maven dont nous aurons besoin pour certains scénarios:

 org.apache.commons commons-collections4 4.2 

La bibliothèque commons-collections4 peut être téléchargée depuis Maven Central.

3. Création de flux à partir de collections

L'approche de base pour créer un Stream à partir de n'importe quel type de collection consiste à appeler les méthodes stream () ou parallelStream () sur la collection en fonction du type de flux requis:

Collection collection = Arrays.asList("a", "b", "c"); Stream streamOfCollection = collection.stream(); 

Notre collection aura très probablement une source externe à un moment donné, nous nous retrouverons probablement avec une méthode similaire à celle ci-dessous lors de la création de flux à partir de collections:

public Stream collectionAsStream(Collection collection) { return collection.stream(); } 

Cela peut causer des problèmes. Lorsque la collection fournie pointe vers une référence null , le code lèvera une NullPointerException au moment de l'exécution.

La section suivante explique comment nous pouvons nous protéger contre cela.

4. Rendre les flux de collection créés nuls

4.1. Ajouter des vérifications pour éviter les déréférences nulles

Pour éviter les exceptions de pointeur nul non intentionnelles , nous pouvons choisir d'ajouter des vérifications pour empêcher les références nulles lors de la création de flux à partir de collections:

Stream collectionAsStream(Collection collection) { return collection == null ? Stream.empty() : collection.stream(); } 

Cette méthode, cependant, a quelques problèmes.

Premièrement, la vérification de la valeur NULL empêche la logique métier de réduire la lisibilité globale du programme.

Deuxièmement, l'utilisation de null pour représenter l'absence d'une valeur est considérée comme une mauvaise approche après Java SE 8: il existe une meilleure façon de modéliser l'absence et la présence d'une valeur.

Il est important de garder à l'esprit qu'une collection vide n'est pas la même chose qu'une collection nulle . Alors que le premier indique que notre requête n'a pas de résultats ou d'éléments à afficher, le second suggère qu'une sorte d'erreur vient de se produire pendant le processus.

4.2. Utilisez la méthode emptyIfNull de la bibliothèque CollectionUtils

Nous pouvons choisir d'utiliser la bibliothèque CollectionUtils d' Apache Commons pour nous assurer que notre flux est nullement sûr. Cette bibliothèque fournit une méthode emptyIfNull qui retourne une collection vide immuable étant donné une collection nulle comme argument, ou la collection elle-même sinon:

public Stream collectionAsStream(Collection collection) { return emptyIfNull(collection).stream(); } 

C'est une stratégie très simple à adopter. Cependant, cela dépend d'une bibliothèque externe. Si une politique de développement logiciel restreint l'utilisation d'une telle bibliothèque, cette solution est rendue nulle et non avenue.

4.3. Utilisez Java 8 en option

Optionnel de Java SE 8 est un conteneur à valeur unique qui contient une valeur ou non. Lorsqu'une valeur est manquante, le conteneur facultatif est dit vide.

L'utilisation facultative peut être considérée comme la meilleure stratégie globale pour créer une collection de sécurité nulle à partir d'un flux.

Voyons comment nous pouvons l'utiliser suivi d'une discussion rapide ci-dessous:

public Stream collectionToStream(Collection collection) { return Optional.ofNullable(collection) .map(Collection::stream) .orElseGet(Stream::empty); } 
  • Facultatif.ofNullable (collection) crée unobjet Facultatif à partir de la collection transmise. Unobjet facultatif videest créé si la collection est nulle.
  • map (Collection :: stream) extrait la valeur contenue dans l'objet facultatif comme argument de laméthode map ( Collection.stream () )
  • orElseGet (Stream :: empty) renvoie la valeur de secours dans le cas où l'objet facultatif est vide, c'est-à-dire que la collection transmise est nulle .

Par conséquent, nous protégeons proactivement notre code contre les exceptions de pointeur nul non intentionnelles .

4.4. Utilisez Stream OfNullable de Java 9

Examen de notre exemple ternaire précédent dans la section 4.1. et considérant la possibilité que certains éléments puissent être null au lieu de la Collection , nous avons à notre disposition la méthode ofNullable dans la classe Stream .

Nous pouvons transformer l'exemple ci-dessus en:

Stream collectionAsStream(Collection collection) { return collection.stream().flatMap(s -> Stream.ofNullable(s)); }

5. Conclusion

Dans cet article, nous avons brièvement revisité comment créer un flux à partir d'une collection donnée. Nous avons ensuite exploré les trois stratégies clés pour nous assurer que le flux créé est null-safe lorsqu'il est créé à partir d'une collection.

Enfin, nous avons souligné la faiblesse d'utiliser chaque stratégie le cas échéant.

Comme d'habitude, le code source complet qui accompagne l'article est disponible à l'adresse over sur GitHub.