Certaines méthodes couratnes pour créer des flux en Java 8 incluent :
Création à partir d'un tableau La méthode statique Arrays.stream() permet d'obtenir un flux à partir d'un tableau.
String[] monTableau = { "a", "b", "c", "d", "e", "f", "g" };
Stream<String> fluxTableau = Arrays.stream(monTableau);
Création à partir d'une collection L'interface Collection fournit les méthodes stream() et parallelStream() pour créer des flux.
List<String> maListe = new ArrayList<>();
maListe.add("a");
maListe.add("b");
maListe.add("c");
Stream<String> fluxListe = maListe.stream();
Création à partir de valeurs La méthode Stream.of() crée un flux à partir d'une liste explicite de valeurs. Elle accepte un nombre variable d'arguments.
Stream<Integer> fluxValeurs = Stream.of(1, 2, 3, 4, 5, 6);
Création à partir d'une fonction Les méthodes Stream.iterate() et Stream.generate() permettent de créer des flux infinis.
// Flux infini de nombres aléatoires, limité à 5 éléments
Stream<Double> fluxAleatoire = Stream.generate(Math::random).limit(5);
// Flux infini d'entiers séquentiels, limité à 5 éléments
Stream<Integer> fluxSequentiel = Stream.iterate(0, n -> n + 1).limit(5);
Important : Lors de l'utilisation de flux infinis, il est crucial d'appliquer la méthode limit() pour éviter une création de données illimitée.
Exemples de regroupement et de recherche de valeurs extrêmes
Pour illustrer les opérations de rgeroupement et de recherche de valeurs extrêmes, nous utiliserons une classe Etudiant définie ci-dessous. L'utilisation de Lombok est recommandée pour réduire le code répétitif.
Classe Étudiant
package com.exemple;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* Dépendance Lombok nécessaire :
* <dependency>
* <groupId>org.projectlombok</groupId>
* <artifactId>lombok</artifactId>
* <version>1.18.16</version>
* </dependency>
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Etudiant {
private long id;
private String nom;
private int age;
private int niveau;
private String specialite;
private String universite;
}
Code d'exemple
Ce code démontre l'utilisation des flux avec des objets complexes, des types de données primitifs et des collections de maps.
package com.exemple;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TraitementFlux {
public static void main(String[] args) {
// --- Démonstration avec objets complexes ---
List<Etudiant> etudiants = new ArrayList<Etudiant>() {
{
add(new Etudiant(20160001, "Zhuo", 20, 1, "Génie Civil", "Université de Wuhan"));
add(new Etudiant(20160003, "Liu", 22, 3, "Économie", "Université de Wuhan"));
add(new Etudiant(20161001, "Zhang", 21, 2, "Mécanique & Automatique", "Université de Sciences et Technologie de Huazhong"));
add(new Etudiant(20161003, "Li", 23, 4, "Informatique", "Université de Sciences et Technologie de Huazhong"));
add(new Etudiant(20163001, "Wang", 24, 5, "Génie Civil", "Université de Nanjing"));
}
};
// Regroupement par université et comptage
Map<String, Long> compteParUniversite = etudiants.stream().collect(
Collectors.groupingBy(Etudiant::getUniversite, Collectors.counting())
);
// Sortie : {Université de Nanjing=1, Université de Wuhan=2, Université de Sciences et Technologie de Huazhong=2}
System.out.println("Comptage par université : " + compteParUniversite);
// Regroupement par université, tri par nom et obtention des noms uniques
TreeMap<String, Set<String>> nomsParUniversite = etudiants.stream().collect(
Collectors.groupingBy(
Etudiant::getUniversite,
TreeMap::new, // Utilise un TreeMap pour un tri naturel des clés
Collectors.mapping(Etudiant::getNom, Collectors.toSet())
)
);
// Sortie : {Université de Nanjing=[Wang], Université de Wuhan=[Zhuo, Liu], Université de Sciences et Technologie de Huazhong=[Zhang, Li]}
System.out.println("Noms uniques par université : " + nomsParUniversite);
// Regroupement par université pour obtenir la liste complète des étudiants
Map<String, List<Etudiant>> etudiantsParUniversite = etudiants.stream()
.collect(Collectors.groupingBy(Etudiant::getUniversite));
/* Sortie : {
Université de Nanjing=[Etudiant(id=20163001, nom=Wang, age=24, niveau=5, specialite=Génie Civil, universite=Université de Nanjing)],
Université de Wuhan=[
Etudiant(id=20160001, nom=Zhuo, age=20, niveau=1, specialite=Génie Civil, universite=Université de Wuhan),
Etudiant(id=20160003, nom=Liu, age=22, niveau=3, specialite=Économie, universite=Université de Wuhan)
],
Université de Sciences et Technologie de Huazhong=[
Etudiant(id=20161001, nom=Zhang, age=21, niveau=2, specialite=Mécanique & Automatique, universite=Université de Sciences et Technologie de Huazhong),
Etudiant(id=20161003, nom=Li, age=23, niveau=4, specialite=Informatique, universite=Université de Sciences et Technologie de Huazhong)
]
}
*/
System.out.println("Liste des étudiants par université : " + etudiantsParUniversite);
// Recherche de l'étudiant le plus âgé et du plus jeune par âge
Etudiant etudiantPlusAge = etudiants.stream()
.max(Comparator.comparingInt(Etudiant::getAge))
.orElse(null); // Utiliser orElse pour éviter NoSuchElementException
Etudiant etudiantPlusJeune = etudiants.stream()
.min(Comparator.comparingInt(Etudiant::getAge))
.orElse(null);
// Sortie : Étudiant le plus âgé : Etudiant(id=20163001, nom=Wang, age=24, niveau=5, specialite=Génie Civil, universite=Université de Nanjing)
System.out.println("Étudiant le plus âgé : " + etudiantPlusAge);
// Sortie : Étudiant le plus jeune : Etudiant(id=20160001, nom=Zhuo, age=20, niveau=1, specialite=Génie Civil, universite=Université de Wuhan)
System.out.println("Étudiant le plus jeune : " + etudiantPlusJeune);
// --- Démonstration avec des types de données primitifs (Integer) ---
List<Integer> nombres = Arrays.asList(20, 18, 18, 17);
// Regroupement des nombres et comptage de leurs occurrences
Map<Integer, Long> compteParNombre = nombres.stream().collect(
Collectors.groupingBy(n -> n, Collectors.counting())
);
// Sortie : {17=1, 18=2, 20=1}
System.out.println("Comptage des nombres : " + compteParNombre);
// Regroupement des nombres dans un TreeMap, puis obtention de listes
TreeMap<Integer, List<Integer>> listesParNombre = nombres.stream().collect(
Collectors.groupingBy(
n -> n,
TreeMap::new,
Collectors.mapping(n -> n, Collectors.toList())
)
);
// Sortie : {17=[17], 18=[18, 18], 20=[20]}
System.out.println("Listes de nombres par valeur : " + listesParNombre);
// Recherche du nombre maximum et minimum
Integer maxNombre = nombres.stream().max(Integer::compareTo).orElse(null);
Integer minNombre = nombres.stream().min(Integer::compareTo).orElse(null);
System.out.println("Nombre maximum : " + maxNombre); // Sortie : 20
System.out.println("Nombre minimum : " + minNombre); // Sortie : 17
// --- Démonstration avec une liste de Maps ---
List<Map<String, Object>> listeMaps = Arrays.asList(
new HashMap<String, Object>() {{ put("prdTyp", "lon"); put("typ", "2.3"); }},
new HashMap<String, Object>() {{ put("prdTyp", "lon"); put("typ", "1.0"); }},
new HashMap<String, Object>() {{ put("prdTyp", "lpr"); put("typ", "88"); }},
new HashMap<String, Object>() {{ put("prdTyp", "lpr"); put("typ", "99"); }}
);
// Regroupement par la clé "prdTyp"
Map<Object, List<Map<String, Object>>> groupParPrdTyp = listeMaps.stream()
.collect(Collectors.groupingBy(map -> map.get("prdTyp")));
/* Sortie : {
lon=[{prdTyp=lon, typ=2.3}, {prdTyp=lon, typ=1.0}],
lpr=[{prdTyp=lpr, typ=88}, {prdTyp=lpr, typ=99}]
}
*/
System.out.println("Groupement par 'prdTyp' : " + groupParPrdTyp);
// Regroupement par "prdTyp", trié par clé, et extraction des valeurs associées
TreeMap<Object, List<Object>> valuesGroupedByType = listeMaps.stream().collect(
Collectors.groupingBy(
map -> map.get("prdTyp"),
TreeMap::new,
Collectors.mapping(map -> map.get("typ"), Collectors.toList()) // Extraction de la valeur "typ"
)
);
// Sortie : {lpr=[88, 99], lon=[2.3, 1.0]}
System.out.println("Valeurs groupées par 'prdTyp' : " + valuesGroupedByType);
// Recherche de la map avec la valeur "typ" maximale (interprétée comme BigDecimal)
Optional<Map<String, Object>> mapMaxTyp = listeMaps.stream().max(
Comparator.comparing(map -> new BigDecimal((String) map.get("typ")))
);
// Affichage de la valeur "typ" de la map trouvée : 99
mapMaxTyp.ifPresent(map -> System.out.println("Valeur 'typ' maximale : " + map.get("typ")));
// Recherche de la map avec la valeur "typ" minimale (interprétée comme BigDecimal)
Optional<Map<String, Object>> mapMinTyp = listeMaps.stream().min(
(map1, map2) -> new BigDecimal((String) map1.get("typ")).compareTo(new BigDecimal((String) map2.get("typ")))
);
// Affichage de la valeur "typ" de la map trouvée : 1.0
mapMinTyp.ifPresent(map -> System.out.println("Valeur 'typ' minimale : " + map.get("typ")));
}
}