ProgrammationDéveloppeur Java

Expliquez ce qu'est l'API Java Stream, comment l'utiliser correctement pour les opérations de traitement des collections et quelles nuances doivent être prises en compte lors du travail avec des flux de données ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

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 :

  • Les flux sont paresseux : les calculs se produisent uniquement lors de l'opération terminale
  • Après l'opération terminale, le flux est considéré comme fermé
  • Il est possible de passer au traitement parallèle (parallelStream()), mais il faut prendre en compte la sécurité des threads des collections et des fonctions

Questions pièges.

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

Erreurs typiques et anti-patterns

  • Utilisation de variables externes mutables à l'intérieur d'une lambda/stream
  • Attente d'un effet immédiat des opérations intermédiaires (sans opération terminale, rien ne se passe)
  • Application de .parallelStream() à des collections qui ne sont pas thread-safe

Exemple de la vie réelle

Cas négatif

Un 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 :

  • Code compact

Inconvénients :

  • Possibilité de conditions de course, exceptions
  • Violation de la sécurité des threads

Cas positif

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 :

  • Code sécurisé, lisible, efficace
  • Transition facile vers des flux parallèles

Inconvénients :

  • Nécessite une habitude au style fonctionnel