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 -> 1Collecteur 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, CarolgroupingBy à 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 orderEn 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 UnsupportedOperationExceptionCas 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
- groupingBy : classer des éléments
- partitioningBy et comptage
- toMap, joining et summarizing
- Créer un collecteur personnalisé