Historique de la question:
L'API Stream a été ajoutée dans Java 8 pour faciliter la programmation fonctionnelle et le traitement parallèle des collections. Elle offre un moyen pratique de décrire des chaînes d'opérations sur les données via des expressions lambda.
Problème:
Sans l'API Stream, il fallait écrire un code impératif encombrant pour filtrer, trier et agréger des collections. Cela entraînait des risques d'erreurs, compliquait la maintenance et était inefficace pour ajouter manuellement du parallélisme.
Solution:
L'API Stream permet de construire un pipeline d'opérations intermédiaires (intermediate) et terminales (terminal). Les flux sont paresseux, fonctionnent avec les données de manière séquentielle ou parallèle, et le code devient plus compact et expressif.
Exemple de traitement d'une collection :
List<String> names = Arrays.asList("Anna", "Ivan", "Petr", "Eva"); names.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .forEach(System.out::println);
Caractéristiques clés :
parallelStream()), mais il faut prendre en compte la sécurité des threads des collections et des fonctionsPeut-on réutiliser le même flux après sa fermeture ?
Non, toute tentative de réutiliser un flux fermé génère une IllegalStateException. Un flux est à usage unique.
Un changement de la collection d'origine après la création du flux a-t-il un impact ?
Oui, si la collection est modifiée après la création du flux, mais avant l'opération terminale, des ConcurrentModificationException peuvent se produire.
Peut-on utiliser des variables externes modifiables à l'intérieur des opérations de flux ?
Il n'est pas recommandé de le faire, car dans un flux parallèle, cela peut entraîner des erreurs inattendues. Il vaut mieux éviter les effets de bord mutables dans le pipeline Stream.
.parallelStream() à des collections qui ne sont pas thread-safeUn programmeur appelle via Stream une méthode qui modifie une liste externe — cela fonctionne lors d'une exécution séquentielle, mais entraîne un désordre dans la structure des données lors d'une exécution parallèle.
Avantages :
Inconvénients :
Tout le pipeline est construit proprement : les opérations n'ont pas d'effets de bord, seules des collections immuables sont utilisées, et le résultat final est collecté via un collecteur.
Avantages :
Inconvénients :