Guide des méthodes courantes pour manipuler les flux Stream en JDK 8

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();

Étiquettes: JDK 8 Java Stream Collectors Lambda expressions Stream API

Publié le 11 juin à 01h56