0Pricing
Java Academy · Leçon

groupingBy : classer des éléments

Regroupez les éléments d’un flux dans des cartes à l’aide d’une fonction de classification et composez-les avec des collecteurs en aval.

groupingBy : classer des éléments est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Qu’est-ce que groupingBy ?

Collectors.groupingBy() répartit les éléments du stream dans une Map où chaque clé est associée à une liste d’éléments correspondants. C’est l’équivalent de GROUP BY en SQL pour les streams.

import java.util.*;
import java.util.stream.*;

record Person(String name, String city) {}
List<Person> people = List.of(
    new Person("Alice","NYC"), new Person("Bob","LA"),
    new Person("Carol","NYC"), new Person("Dave","LA"),
    new Person("Eve","Chicago")
);

Map<String, List<Person>> byCity =
    people.stream().collect(Collectors.groupingBy(Person::city));
byCity.forEach((city, ps) -> System.out.println(city + ": " + ps.size()));

Collecteur en aval : counting

Combinez groupingBy avec un collecteur en aval pour agréger les éléments au lieu de les énumérer :

Map<String, Long> countByCity =
    people.stream().collect(
        Collectors.groupingBy(Person::city, Collectors.counting())
    );
countByCity.forEach((city, n) -> System.out.println(city + " -> " + n));
// NYC -> 2, LA -> 2, Chicago -> 1

Collecteur en aval : mapping

Utilisez Collectors.mapping() comme collecteur en aval pour transformer les éléments avant de les collecter :

Map<String, List<String>> namesByCity =
    people.stream().collect(
        Collectors.groupingBy(
            Person::city,
            Collectors.mapping(Person::name, Collectors.toList())
        )
    );
namesByCity.forEach((city, names) -> System.out.println(city + ": " + names));

Collecteur en aval : joining

Concaténez les noms de chaque groupe en une seule chaîne séparée par des virgules :

Map<String, String> joinedByCity =
    people.stream().collect(
        Collectors.groupingBy(
            Person::city,
            Collectors.mapping(Person::name, Collectors.joining(", "))
        )
    );
joinedByCity.forEach((city, s) -> System.out.println(city + ": " + s));
// NYC: Alice, Carol

groupingBy à plusieurs niveaux

Imbriquez les appels à groupingBy pour effectuer une classification multidimensionnelle :

record Employee(String name, String dept, String level) {}
List<Employee> emps = List.of(
    new Employee("A","Eng","Junior"), new Employee("B","Eng","Senior"),
    new Employee("C","HR","Junior"), new Employee("D","HR","Senior")
);

Map<String, Map<String, List<Employee>>> grouped =
    emps.stream().collect(
        Collectors.groupingBy(Employee::dept,
            Collectors.groupingBy(Employee::level))
    );
grouped.forEach((dept, levels) -> levels.forEach((level, list) ->
    System.out.println(dept+"/"+level+": "+list.size())));

Contrôler le type de Map

Par défaut, groupingBy produit une HashMap. Utilisez la surcharge à trois arguments pour spécifier un autre type de Map, par exemple TreeMap pour obtenir des clés triées :

Map<String, Long> sorted =
    people.stream().collect(
        Collectors.groupingBy(Person::city, TreeMap::new, Collectors.counting())
    );
System.out.println(sorted); // keys in alphabetical order

En aval : averagingInt

Calculez les moyennes pour chaque groupe :

record Product(String category, int price) {}
List<Product> products = List.of(
    new Product("A",10), new Product("A",20),
    new Product("B",15), new Product("B",25)
);

Map<String, Double> avgPrice =
    products.stream().collect(
        Collectors.groupingBy(Product::category,
            Collectors.averagingInt(Product::price))
    );
avgPrice.forEach((cat, avg) -> System.out.printf("%s: %.1f%n", cat, avg));

En aval : toUnmodifiableList

Utilisez Collectors.toUnmodifiableList() en aval pour produire des groupes immuables :

Map<String, List<String>> immutable =
    people.stream().collect(
        Collectors.groupingBy(Person::city,
            Collectors.mapping(Person::name, Collectors.toUnmodifiableList()))
    );
// Attempting to modify throws UnsupportedOperationException

Cas concret : récapitulatif des commandes

Regroupez les commandes par statut et additionnez les montants de chaque groupe :

record Order(String status, double amount) {}
List<Order> orders = List.of(
    new Order("PAID", 50.0), new Order("PENDING", 30.0),
    new Order("PAID", 75.0), new Order("CANCELLED", 20.0)
);

Map<String, Double> totalByStatus =
    orders.stream().collect(
        Collectors.groupingBy(Order::status,
            Collectors.summingDouble(Order::amount))
    );
totalByStatus.forEach((s, t) -> System.out.printf("%s: $%.2f%n", s, t));

Considérations relatives aux performances

groupingBy conserve tous les éléments en mémoire. Pour les ensembles de données très volumineux, envisagez de traiter les éléments par lots ou d’utiliser un GROUP BY au niveau de la base de données. Le collecteur en aval s’exécute pour chaque élément : gardez-le léger afin d’éviter un comportement en O(n²).

Combiner filter et sorted

Enchaînez les opérations du stream avant la collecte pour filtrer ou trier les données au préalable :

Map<String, Long> activeCities =
    people.stream()
          .filter(p -> !p.city().equals("Chicago"))
          .collect(Collectors.groupingBy(Person::city, Collectors.counting()));
System.out.println(activeCities); // {NYC=2, LA=2}

Vérification rapide

Quel type produit Collectors.groupingBy(Person::city) lorsqu’il est utilisé avec collect() ?

Récapitulatif : groupingBy

Points essentiels :

  • groupingBy(classifier) → Map<K, List<T>>
  • Combinez-le avec des collecteurs en aval : counting, mapping, joining, summarizing
  • Imbriquez groupingBy pour effectuer une classification multidimensionnelle
  • Utilisez la surcharge à trois arguments pour contrôler le type de Map obtenu, par exemple TreeMap

Questions Fréquemment Posées

La leçon « groupingBy : classer des éléments » est-elle gratuite ?

Oui — le texte complet de « groupingBy : classer des éléments » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « groupingBy : classer des éléments » ?

Regroupez les éléments d’un flux dans des cartes à l’aide d’une fonction de classification et composez-les avec des collecteurs en aval. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « groupingBy : classer des éléments » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. groupingBy : classer des éléments
  2. partitioningBy et comptage
  3. toMap, joining et summarizing
  4. Créer un collecteur personnalisé
← Retour à Java Academy