Regrouper une liste en une map basée sur des clés combinées
Pour collecter les éléments d'une liste dans une map où la clé est une concaténation de deux champs, on peut utiliser Collectors.groupingBy avec une expression lambda.
Map<String, List<TransactionEntree>> regroupementParRef = listeTransactions.stream()
.collect(Collectors.groupingBy(
transaction -> transaction.getReference() + "_" + transaction.getPeriode()
));
Agréger des données en groupes multiples avec des statistiques
On peut imbriquer des collecteurs pour regrouper par deux attributs et effectuer des calculs comme des sommes ou des moyennes.
Map<String, Map<String, BigDecimal>> totauxParCategorie = fluxDonnees.collect(
Collectors.groupingBy(
EntreeComptable::getCategoriePrincipale,
Collectors.groupingBy(
EntreeComptable::getSousCategorie,
Collectors.summingBigDecimal(EntreeComptable::getMontant)
)
)
);
Compter les occurrences après un regroupement par deux champs
Pour obtenir le nombre d'éléments dans chaque sous-groupe, on applique Collectors.counting() comme second collecteur.
Map<String, Map<Integer, Long>> comptageParDepartement = listeAnomalies.stream()
.collect(Collectors.groupingBy(
Anomalie::getDepartement,
Collectors.groupingBy(Anomalie::getTypeAnomalie, Collectors.counting())
));
Effectuer une somme avec gestion des valeurs nulles après regroupement
En utilisant Collectors.reducing, on peut calculer des totaux en gérant explicitement les valeurs nulles pour éviter les erreurs.
Map<String, Map<String, BigDecimal>> soldeParService = donneesComptables.collect(
Collectors.groupingBy(
Enregistrement::getService,
Collectors.groupingBy(
Enregistrement::getProjet,
Collectors.reducing(
BigDecimal.ZERO,
e -> Optional.ofNullable(e.getSolde()).orElse(BigDecimal.ZERO),
BigDecimal::add
)
)
)
);
Sommer une propriété de type BigDecimal dans une liste
On peut filtrer les éléments non nuls et réduire la collection pour obtenir la somme totale d'un attribut numérique.
BigDecimal totalDebit = listeOperations.stream()
.filter(op -> op.getMontantDebit() != null)
.map(Operation::getMontantDebit)
.reduce(BigDecimal.ZERO, BigDecimal::add);
Transformer une liste d'objets en une nouvelle collection
L'opération map permet de convertir chaque élément en un autre type, et collect assemble les résultats dans une liste.
List<FicheClient> fichesTransformees = listePersonnes.stream()
.map(personne -> new FicheClient(personne.getIdentifiant(), personne.getNomComplet()))
.collect(Collectors.toList());
Créer une map avec un attribut comme clé et l'objet lui-même comme valeur
Pour indexer une liste par un attribut unique, on utilise Collectors.toMap avec une fonction d'identité et une stratégie de fusion en cas de doublons.
Map<String, Employe> annuaireParTelephone = listeEmployes.stream()
.collect(Collectors.toMap(
Employe::getNumeroTelephone,
employe -> employe,
(premier, second) -> premier // Garder le premier en cas de conflit
));
Mapper une collection vers un ensemble d'objets différents
En combinant map et collect, on peut convertir une liste de source en une liste de destination avec des propriétés sélectionnées.
List<ResumeProjet> resumesProjets = listeProjets.stream()
.map(projet -> new ResumeProjet(projet.getCode(), projet.getTitre()))
.collect(Collectors.toList());
Éliminer les doublons basés sur une propriété spécifique
En utiilsant Collectors.toMap avec une fonction de merge, on peut conserver uniquement la première occrurence pour chaque valeur d'attribut, puis extraire les valeurs de la map.
Collection<Utilisateur> utilisateursUniques = listeUtilisateurs.stream()
.collect(Collectors.toMap(
Utilisateur::getAdresseEmail,
utilisateur -> utilisateur,
(existant, nouveau) -> existant
))
.values();