27/12/2024
API Stream
• Un Stream permet d’exécuter une opération
ensembliste de manière séquentielle ou en parallèle
sur une séquence d’éléments obtenus à partir d’une
source dans le but d’obtenir un résultat.
• L’API Stream de Java facilite l’exécution de
traitements sur les données (surtout des collections)
de manière séquentielle ou parallèle.
64
Éléments concernés par un Stream
• Les éléments traités par un Stream sont fournis par
une source qui peut être de différents types :
• une collection.
• un tableau.
• un flux d’E/S.
• une chaîne de caractères.
• une fonction qui génère des données, etc.
65
27/12/2024
Propriétés des Streams
• Un Stream n’a pas de stockage :
• un Stream ne stocke aucun élément, mais extrait
des éléments d'une source de données à la
demande et les transmet à un pipeline d’opérations
pour traitement.
66
Propriétés des Streams
• Un Stream peut être infini :
• étant donné qu’une fonction peut générer un
nombre infini d’éléments et qu’un flux peut en
extraire des données à la demande, il est possible
d’avoir un flux représentant une séquence
d’éléments de données infinis.
67
Propriétés des Streams
• Les Streams supportent la programmation déclarative
et fonctionnelle :
• Un Stream a besoin uniquement de ce qu’on
souhaite en termes d’opérations (pas le comment).
• Un Stream produit un résultat sans modifier la
source de données.
• Un Stream supporte l’utilisation des expressions
lambda. 68
27/12/2024
Problème
• Considérons une classe « Person » ayant deus
attributs « name » (String) et « age » (int), un
constructeur « Person(String, int) » et des getters
« String getName() » et « int getAge() ».
• Étant donné une listes de jeunes personnes, extraire
les noms des personnes mineurs (personne dont l’âge
est inférieur à18 ans). 69
Solution
avant Java
8
70
Solution avec
l’API Stream
71
27/12/2024
Pipeline d’un Stream
• Les Streams sont utilisés pour effectuer des calculs
constitués d’opérations composées dans des pipelines
de Streams.
• Un pipeline de Stream se compose d’une :
• source de données
• chaîne de 0 ou plusieurs opérations intermédiaires.
• opération terminale.
72
Pipeline d’un Stream
• Une source de données peut être un tableau, une
collection, un canal d’E/S, une fonction génératrice,
etc.
• Une opération intermédiaire transforme un Stream en
un autre Stream.
• Une opération terminale produit un résultat ou un
effet secondaire.
73
74
27/12/2024
Propriétés
• Le type de résultat d’un Stream dépend uniquement de
l’opération du terminal.
• Les Streams sont paresseux : le calcul sur les données
sources n'est effectué que lorsque l’opération du terminal
est lancée et les éléments sources ne sont consommés
qu’en cas de besoin.
• Les Streams ne peuvent pas être réutilisés, on peut
canaliser une seule opération intermédiaire ou finale.
75
76
Filtrage
• Syntaxe : « .filter(prédicat) ».
• « prédicat » est une expression lambda qui représente
une expression booléenne sur un type générique
« T ».
• Pour avoir des éléments distincts, on fait suivre
« .filter(prédicat) » de l’opération intermédiaire
« .distinct() ».
77
27/12/2024
78
Tri
• Syntaxe :
• « .sorted() ».
• « .sorted(comparateur) ».
• La 1ère variante effectue un tri basé sur l’ordre naturel
d’une classe comparable.
• La 2ème variante effectue un tri basé sur comparateur
personnalisé.
79
80
27/12/2024
81
Découpage conditionnel
• « .takeWhile(prédicat) » : cette méthode va extraire
toutes les valeurs du Stream jusqu’à ce qu’elle
rencontre la première valeur qui rend « prédicat » faux.
• « .dropWhile(prédicat) » : cette méthode va sauter
toutes les valeurs du Stream jusqu’à ce qu’elle
rencontre la première valeur qui rend « prédicat » vrai.
82
83
27/12/2024
Découpage inconditionnel
• « .limit(int) » :
• opération intermédiaire qui renvoie un Stream dont
la taille ne dépasse pas la taille demandée.
• Son paramètre doit être un entier positif.
• si le paramètre est égal 0, « limit() » renvoie un
Stream vide.
84
Découpage inconditionnel
• « .skip(int) » :
• opération intermédiaire qui supprime les « n »
premiers éléments d’un Stream.
• Son paramètre doit être un entier positif.
• si le paramètre est supérieur à la taille du Stream,
« skip() » renvoie un Stream vide.
85
86
27/12/2024
Mapping
• « .map(Function<T, R>) » :
• opération intermédiaire qui applique une fonction
sur les éléments d’un Stream.
• Son paramètre est une expression lambda qui doit
être conforme à une fonction ayant un argument de
type « T » et retournant un résultat de type « R ».
87
88
Aplatissement
• « .flatMap() » :
• opération intermédiaire utilisée lorsqu’on veut
transformer l’élément d’un Stream en nouveaux
Streams et que l’on souhaite « aplatir » ces
nouveaux Streams en un seul Stream.
89
27/12/2024
90
Compter les éléments
• « .count() » :
• opération terminale qui renvoie la taille d’un
Stream (résultat de type long).
Consommer les éléments
• « .forEach() » :
• opération terminale qui consomme les éléments
d’un Stream (résultat de type long). 91
92
27/12/2024
Correspondance
• « .anyMatch(prédicat) » :
• Retourne « true » si au moins un élément du Stream
satisfait le prédicat spécifié.
• « .allMatch(prédicat) » :
• Retourne « true » si tous les éléments du Stream satisfont
le prédicat spécifié.
• « .noneMatch(prédicat) » :
• Retourne « true » si aucun un élément du Stream ne
satisfait le prédicat spécifié. 93
94
Retourner un élément
• « .findAny(prédicat) » :
• Retourne un élément (optionnel) du Stream qui
satisfait le prédicat spécifié.
• L’élément retourné doit être de type « Optional »
qui est une classe prédéfinie dans Java.
• Elle est utilisée pour servir en cas d’un Stream dont
le résultat est vide.
95
27/12/2024
96
Combiner les éléments
• « .reduce(prédicat) » :
• Combine les éléments d’un Stream pour retourner
un résultat (somme, maximum, etc).
• L’élément retourné doit être de type « Optional ».
97
98
27/12/2024
Spécialisation de Streams
• L’API Streams fournit des spécialisations de Streams
primitifs qui prennent en charge des méthodes
spécialisées pour travailler avec des Streams de
nombres, afin de rendre les réductions numériques
courantes plus efficaces :
• IntStream
• LongStream
• DoubleStream 99
Spécialisation de Streams
• On peut passer des Streams d’objets aux Streams
primitifs en utilisant l’une des méthodes :
• « mapToInt() »
• « mapToDouble() »
• « mapToLong ».
100
101
27/12/2024
Spécialisation de Streams
• On peut passer des Streams primitifs spécialisés aux
Streams d’objets en utilisant la méthode « boxed() »
ou via l’utilisation de la méthode « mapToObj ».
102
103