








Table des matières
ToggleTop 5 des erreurs courantes avec les Streams Java
Comment éviter les pièges courants des Streams Java.
Premièrement qu’est ce qu’un stream ? Un Stream est une séquence de données sur laquelle on peut effectuer des opérations comme filtrer, trier, ou transformer les éléments, de manière fluide et souvent en parallèle. Il permet de traiter des collections (comme des listes) de manière déclarative et efficace, sans avoir à gérer explicitement les boucles.
1. Modifier la source pendant le traitement
Problème : Modifier une collection pendant qu'elle est traitée provoque des erreurs comme ConcurrentModificationException
.
Solution : Créez une nouvelle collection pour stocker les résultats.
List<Integer> transformedList = list.stream()
.map(x -> x + 1)
.collect(Collectors.toList());
2. Réutiliser un Stream déjà consommé
Problème : Les Streams ne peuvent pas être réutilisés après une opération terminale.
Solution : Créez un nouveau Stream pour chaque opération.
List<String> list = List.of("a", "b", "c");
list.stream().forEach(System.out::println);
3. Mauvaise gestion des Parallel Streams
Problème : Les Parallel Streams sont utiles pour traiter de grandes collections de données en parallèle, mais leur utilisation avec des petites collections peut entraîner des problèmes de concurrence, de synchronisation ou des ralentissements. Pour maximiser leur efficacité, il est recommandé de les utiliser uniquement avec des collections suffisamment grandes, où le parallélisme apporte un vrai gain de performance.
Solution : Utilisez-les uniquement pour des collections volumineuses.
list.stream().forEach(System.out::println); // Stream séquentiel
4. Effets de bord dans les opérations Stream
Problème : Ajouter des effets de bord complique la maintenance et entraîne des comportements imprévisibles.
Qu’est ce que les effets de bord : Un effet de bord se produit lorsqu'une fonction ou une opération modifie quelque chose en dehors de son propre fonctionnement interne, comme une variable globale ou un objet externe. Par exemple, si une méthode modifie une variable en dehors de sa portée, c'est un effet de bord. Cela peut rendre le programme difficile à prédire et à maintenir.
Solution : Utilisez peek()
pour inspecter les valeurs sans modifier l’état externe.
list.stream()
.peek(System.out::println)
.map(x -> x * 2)
.collect(Collectors.toList());
5. Mauvaise collecte avec Collectors.toMap
Problème : Les collisions de clés entraînent une IllegalStateException
.
Qu’est ce qu’une collision de clés ? Une collision de clés se produit lorsqu'un Stream contient plusieurs éléments avec la même clé, mais que toMap
essaie de les placer dans une carte (Map
). Cela crée un conflit, car une clé dans une carte ne peut pas avoir plusieurs valeurs.
Solution : Fournissez une fonction de fusion pour gérer les collisions.
Map<Integer, String> map = List.of("apple", "bat", "ant").stream()
.collect(Collectors.toMap(
String::length,
Function.identity(),
(existing, replacement) -> existing
));