Les Col­lec­tors d’un Stream sont une fonction puissante de l’API Stream de Java 8 grâce à laquelle vous pouvez ras­sem­bler et traiter ef­fi­ca­ce­ment les données. Nous vous ex­pli­quons la structure et les pos­si­bi­li­tés d’uti­li­sa­tion de la méthode Collect de Java.

Quels sont les domaines d’ap­pli­ca­tion de Java Collect() ?

Un Collector d’un Stream peut être utilisé pour créer une liste, un ensemble ou une carte à partir d’un Stream. Un Stream est une séquence d’éléments traités les uns à la suite des autres. L’interface Collector propose un ensemble d’opé­ra­tions de réduction pour les données du pipeline d’un Stream. Il s’agit d’opé­ra­tions finales qui col­lec­tent et ras­semblent les résultats des étapes in­ter­mé­diaires.

Les Col­lec­tors peuvent par exemple être utilisés pour filtrer ou trier des objets dans un Stream. Il est également possible de procéder à une agré­ga­tion, par exemple ad­di­tion­ner des nombres, regrouper des chaînes ou compter des éléments. En outre, les Col­lec­tors disposent de fonctions per­met­tant de trans­for­mer le contenu d’un Stream en une structure spé­ci­fique. Vous pouvez donc par exemple convertir une liste en une carte. Les re­grou­pe­ments aident à ca­té­go­ri­ser les éléments pré­sen­tant les mêmes ca­rac­té­ris­tiques ou con­di­tions. Mais avant tout, les Col­lec­tors d’un Stream ont l’avantage de traiter les données en parallèle sur plusieurs threads. Les opé­ra­tions peuvent ainsi être exécutées bien plus ra­pi­de­ment et ef­fi­ca­ce­ment, notamment pour d’im­por­tants volumes de données.

Syntaxe de Java Collect()

La méthode accepte comme argument un Collector qui définit comment les éléments du Stream doivent être re­cueil­lis et agrégés. Un Collector est une interface qui met à dis­po­si­tion diverses méthodes visant à réunir les éléments d’un Stream sous une forme spé­ci­fique, par exemple une liste, un ensemble ou une carte.

Il existe deux types de méthodes Collect en Java :

  1. <R> R collect(Supplier<R> supplier, Bi­Con­su­mer<R, ? super T> ac­cu­mu­la­tor,Bi­Con­su­mer<R, R> combiner)
  2. <R, A> R collect(Collector<? super T, A, R> collector)

La première variante possède trois fonctions comme argument :

  • supplier : crée un conteneur qui sera utilisé pour le résultat in­ter­mé­diaire.
  • ac­cu­mu­la­tor : calcule le résultat final.
  • combiner : combine les résultats des opé­ra­tions pa­ral­lèles du Stream.

Ces Col­lec­tors pré­dé­fi­nis sont déjà inclus dans la bi­blio­thèque standard et peuvent fa­ci­le­ment être importés et utilisés.

La deuxième variante utilise un Collector comme argument et renvoie le résultat.

  • R : le type du résultat
  • T : le type des éléments dans le Stream
  • A : le type de la fonction ac­cu­mu­la­tor qui en­re­gistre l’état in­ter­mé­diaire de l’opération du Collector
  • collector : exécute l’opération de réduction

En utilisant ces variantes, les dé­ve­lop­peurs peuvent créer des Col­lec­tors sur mesure spé­cia­le­ment conçus selon leurs exigences et offrant un niveau élevé de flexi­bi­lité et de contrôle sur le processus de réduction.

Exemples pratiques d’uti­li­sa­tion de Java Collect()

Nous il­lus­trons ci-après plusieurs fonctions de la méthode « Stream.collect() ». Vous devez déjà être fa­mi­lia­risé avec les opé­ra­teurs Java basiques avant de passer au Col­lec­tion Framework.

Lier une liste de chaînes de ca­rac­tères

Avec Collect() en Java, vous pouvez con­ca­té­ner une liste de chaînes de ca­rac­tères pour obtenir une nouvelle chaîne de ca­rac­tères :

List<String> letters = List.of("a", "b", "c", "d", "e");
// sans la fonction combiner
StringBuilder result = letters.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result.toString());
// avec la fonction combiner
StringBuilder result1 = letters.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result1.toString());
Java

Nous obtenons le résultat suivant :

abcde
a, b, c, d, e
Java

Dans le premier calcul se trouve seulement une instance de String­Buil­der qui n’utilise pas la fonction combiner. C’est pourquoi le résultat obtenu est « abcde ».

Dans le deuxième résultat, nous cons­ta­tons que la fonction combiner réunit les instances String­Buil­der et les sépare par une virgule.

Réunir des éléments en une liste via toList()

Grâce à la fonction « filter() », nous pouvons sé­lec­tion­ner des éléments spé­ci­fiques dans une liste et les en­re­gis­trer dans une nouvelle liste avec « toList() ».

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
List<Integer> oddNumbers = numbers.stream().filter(x -> x % 2 != 0).collect(Collectors.toList());
System.out.println(oddNumbers);
Java

La nouvelle liste contient à présent uni­que­ment les nombres impairs :

[1, 3, 5, 7]
Java

Réunir des éléments en un ensemble via toSet()

De la même manière, nous pouvons créer un nouvel ensemble à partir des éléments sé­lec­tion­nés. Dans un ensemble, les données sont dé­sor­don­nées.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Set<Integer> evenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
System.out.println(evenNumbers);
Java

Le résultat est le suivant :

[2, 4, 6]
Java

Réunir des éléments en une carte via toMap()

Une carte associée à Collect() en Java affecte une valeur à chaque clé.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Map<Integer, String> mapEvenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0)
    .collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapEvenNumbers);
Java

Dans le résultat, nous cons­ta­tons que l’entrée, composée de chiffres pairs, s’est vue affectée des valeurs iden­tiques :

{2=2, 4=4, 6=6}
Java

Combiner des éléments en une chaîne de ca­rac­tères via joining()

La méthode « joining() » ajoute chaque élément du Stream dans l’ordre dans lequel il apparaît et utilise un sé­pa­ra­teur pour séparer les éléments. Le sé­pa­ra­teur est indiqué en tant qu’argument de « joining() ». Si aucun sé­pa­ra­teur n’est indiqué, « joining() » utilise la chaîne vide « “” ».

jshell> String result1 = Stream.of("a", "b", "c").collect(Collectors.joining());
jshell> String result2 = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
Java

Le résultat est le suivant :

result1 ==> "abc"
result2 ==> "{a,b,c}"
Java
Aller au menu principal