L’API streams a été introduite avec Java 8 pour permettre la programmation fonctionnelle. Un stream (flux) est une représentation d’une séquence sur laquelle il est possible d’appliquer des opérations.

L’api Stream permet  :

  • D’optimiser les traitements exécutés grâce au lazyness et à l’utilisation d’opérations de type short-circuiting qui permettent d’interrompre les traitements avant la fin si une condition est atteinte
  • Exécuter certains traitements en parallèle à la demande du développeur

Un Stream permet d’exécuter une agrégation d’opérations 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.

**Exemple :

 
double tailleMoyenneDesHommes = employes 
		.stream() 
		.filter(e -> e.getGenre() == Genre.HOMME) 
		.mapToInt(e -> e.getTaille()) 
		.average() 
		.orElse(0);
 

Un Stream permet d’exécuter des opérations sur un ensemble de données obtenues à partir d’une source afin de générer un résultat.

**Exemple sur une List :

List<String> maListe = Arrays.asList("a1", "a2", "b2", "b1", "c1"); 
 
maListe.stream() 
	.filter(s -> s.startsWith("b"))
	.map(String::toUpperCase) 
	.sorted() 
	.forEach(System.out::println); }

Différence entre une collection et un Stream :

Une collection est une structure qui stocke un ensemble de données en mémoire. Les traitements sur une collection, sans utiliser les Streams, nécessitent de réaliser une itération sur tout ou partie des éléments de la collection par exemple en utilisant l’instruction for.

**Traitement de collection :

List<Personne> personnes = new ArrayList(List.of("Arthur","Pierre"));// ... code pour obtenir une liste de personnes 
List<Long> ids = new ArrayList<>(personnes.size()); 
for(Personne p: personnes){
	 ids.add(p.getId()); 
}

Avec un Stream, les opérations à réaliser sont décrites mais l’itération ou les itérations pour exécuter ces traitements sont réalisées en interne lors de l’exécution de la méthode terminale du Stream.

**Traitement en mode Stream :

List<Personne> personnes = new ArrayList(List.of("Arthur","Pierre"));
List<Long> ids = personne.stream() 
	.map(Personne::getId) 
	.collect(toList());

**Tableau des opérations intermédiaires :

OpérationRôle
filterFiltrer tous les éléments pour n’inclure dans le Stream de sortie que les éléments qui satisfont le Predicat
mapRenvoyer un Stream qui contient le résultat de la transformation de chaque élément de type T en un élément de type R
mapToxxx(Int, Long or Double)Renvoyer un Stream qui contient le résultat de la transformation de chaque élément de type T en un type primitif xxx
flatMapRenvoyer un Stream avec l’ensemble des éléments contenus dans les Stream retournés par l’application de la Function sur les éléments de type T. Ainsi chaque élément de type T peut renvoyer zéro, un ou plusieurs éléments de type R.
flatMapToxxx (Int, Long or Double)Renvoyer un Stream avec l’ensemble des éléments contenus dans les xxxStream retournés par l’application de la Function sur les éléments de type T. Ainsi chaque élément de type T peut renvoyer zéro, un ou plusieurs éléments de type primitif xxx.
distinctRenvoyer un Stream dont les doublons ont été retirés. La détection des doublons se fait en invoquant la méthode equals()
sortedRenvoyer un Stream dont les éléments sont triés dans un certain ordre. La surcharge sans paramètre tri dans l’ordre naturel : le type T doit donc implémenter l’interface Comparable car c’est sa méthode compareTo() qui est utilisée pour la comparaison des éléments deux à deux

La surcharge avec un Comparator l’utilise pour déterminer l’ordre de tri.
peekRenvoyer les éléments du Stream et leur appliquer le Consumer fourni en paramètre
limitRenvoyer un Stream qui contient au plus le nombre d’éléments fournis en paramètre
skipRenvoyer un Stream dont les n premiers éléments ont été ignorés, n correspondant à la valeur fournie en paramètre
sequentialRenvoyer un Stream équivalent dont le mode d’exécution des opérations est séquentiel
parallelRenvoyer un Stream équivalent dont le mode d’exécution des opérations est en parallèle
unorderedRenvoyer un Stream équivalent dont l’ordre des éléments n’a pas d’importance
onCloseRenvoyer un Stream équivalent dont le handler fourni en paramètre sera exécuté à l’invocation de la méthode close(). L’ordre d’exécution de plusieurs handlers est celui de leur déclaration. Tous les handlers sont exécutés même si un handler précédent à lever une exception.

**Tableau des opérations terminal :

MethodeRôle
forEachExécuter le Consumer sur chacun des éléments du Stream
forEachOrderedExécuter le Consumer sur chacun des éléments du Stream en respectant l’ordre de éléments si le Stream en défini un
toArrayObject[] toArray()

Renvoyer un tableau contenant les éléments du Stream
Java<br><A> A[] toArray(IntFunction<A[]> generator)<br>

Renvoyer un tableau contenant les éléments du Stream : le tableau est créé par la fonction fournie
ReduceRéaliser une opération de réduction qui accumule les différents éléments du Stream grâce à la fonction fournie
collectRéaliser une opération de réduction avec le Collector fourni en paramètre
minRenvoyer le plus petit élément du Stream selon le Comparator fourni
maxRenvoyer le plus grand élément du Stream selon le Comparator fourni
countRenvoyer le nombre d’éléments contenu dans le Stream
anyMatchRetourner un booléen qui indique si au moins un élément valide le Predicate
allMatchRetourner un booléen qui indique si tous les éléments valident le Predicate
noneMatchRetourner un booléen qui indique si aucun élément ne valide le Predicate
findFirstRetourner un Optional qui encapsule le premier élément validant le Predicate s’il existe
findAnyRetourner un Optional qui encapsule élément validant le Predicate s’il existe
iteratorRenvoyer un Iterator qui permet de réaliser une itération sur tous les éléments en dehors du Stream
spliteratorRenvoyer un Spliterator pour les éléments du Stream

L’API stream est très complète et utile pour plus d’informations voir les sources.

Sources:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html https://www.jmdoudoux.fr/java/dej/chap-streams.htm