partitioningBy et comptage
Divisez un flux en deux groupes avec partitioningBy et comptez les éléments avec counting.
partitioningBy et comptage est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 2 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.
Bases de partitioningBy
Collectors.partitioningBy(predicate) divise un stream en exactement deux groupes — true et false — et renvoie une Map<Boolean, List<T>>.
import java.util.*;
import java.util.stream.*;
List<Integer> nums = List.of(1,2,3,4,5,6,7,8,9,10);
Map<Boolean, List<Integer>> evenOdd =
nums.stream().collect(Collectors.partitioningBy(n -> n % 2 == 0));
System.out.println(evenOdd.get(true)); // [2, 4, 6, 8, 10]
System.out.println(evenOdd.get(false)); // [1, 3, 5, 7, 9]partitioningBy ou filter
Contrairement à filter, partitioningBy conserve simultanément les deux groupes — ce qui est utile lorsque vous avez besoin des deux parties de la partition.
record Student(String name, int score) {}
List<Student> students = List.of(
new Student("Alice",90), new Student("Bob",55),
new Student("Carol",72), new Student("Dave",48)
);
Map<Boolean, List<Student>> result =
students.stream().collect(
Collectors.partitioningBy(s -> s.score() >= 60)
);
System.out.println("Passed: " + result.get(true).size());
System.out.println("Failed: " + result.get(false).size());Collecteur en aval avec partitioningBy
Combinez partitioningBy avec un collecteur en aval, exactement comme groupingBy :
Map<Boolean, Long> passFailCount =
students.stream().collect(
Collectors.partitioningBy(
s -> s.score() >= 60,
Collectors.counting()
)
);
System.out.println("Passed: " + passFailCount.get(true));
System.out.println("Failed: " + passFailCount.get(false));Collecteur counting()
Collectors.counting() compte le nombre d’éléments du stream, ou du groupe en aval. C’est l’équivalent pratique de reducing(0L, e -> 1L, Long::sum).
long count = Stream.of("a","bb","ccc","dddd")
.collect(Collectors.counting());
System.out.println(count); // 4
// Same as:
long count2 = Stream.of("a","bb","ccc","dddd").count();
// Use counting() as a downstream; use .count() as a terminal opcounting() comme collecteur en aval
counting() est particulièrement utile en aval de groupingBy/partitioningBy :
List<String> words = List.of("cat","dog","car","door","cup","dune");
Map<Character, Long> byFirstLetter =
words.stream().collect(
Collectors.groupingBy(w -> w.charAt(0), Collectors.counting())
);
byFirstLetter.forEach((c, n) -> System.out.println(c + ": " + n));
// c: 3, d: 3Partitionner en noms
Extrayez les noms de chaque partition à l’aide d’un collecteur mapping en aval :
Map<Boolean, List<String>> namesByPass =
students.stream().collect(
Collectors.partitioningBy(
s -> s.score() >= 60,
Collectors.mapping(Student::name, Collectors.toList())
)
);
System.out.println("Passed: " + namesByPass.get(true));
System.out.println("Failed: " + namesByPass.get(false));Combiner counting et summarizingInt
Collectors.summarizingInt() calcule le nombre, la somme, le minimum, le maximum et la moyenne en un seul passage :
IntSummaryStatistics stats =
students.stream().collect(
Collectors.summarizingInt(Student::score)
);
System.out.println("Count: " + stats.getCount());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());Cas concret : répartition pour un test A/B
Répartissez les utilisateurs entre un groupe témoin et un groupe de traitement pour un test A/B :
record User(String id, boolean isInTreatment) {}
List<User> users = List.of(
new User("u1",true), new User("u2",false),
new User("u3",true), new User("u4",false)
);
Map<Boolean, Long> split =
users.stream().collect(
Collectors.partitioningBy(User::isInTreatment, Collectors.counting())
);
System.out.println("Treatment: " + split.get(true)); // 2
System.out.println("Control: " + split.get(false)); // 2Carte de fréquences avec groupingBy + counting
Comptez les occurrences de chaque élément, afin de créer une carte de fréquences des mots :
List<String> words2 = List.of("apple","banana","apple","cherry","banana","apple");
Map<String, Long> freq =
words2.stream().collect(
Collectors.groupingBy(w -> w, Collectors.counting())
);
freq.entrySet().stream()
.sorted(Map.Entry.<String,Long>comparingByValue().reversed())
.forEach(e -> System.out.println(e.getKey()+": "+e.getValue()));partitioningBy renvoie toujours les deux clés
Contrairement à groupingBy, partitioningBy renvoie toujours une carte contenant les clés true et false, même si l’un des groupes est vide. Cela évite les NullPointerExceptions lors de l’appel à map.get(true).
List<Integer> allEven = List.of(2,4,6);
Map<Boolean, List<Integer>> m =
allEven.stream().collect(Collectors.partitioningBy(n -> n % 2 != 0));
System.out.println(m.get(true)); // [] (empty, not null)
System.out.println(m.get(false)); // [2, 4, 6]Performances : un seul passage
partitioningBy et counting fonctionnent tous deux en un seul passage du stream, en O(n). Ils ne nécessitent pas de tri. Ils sont donc bien plus efficaces que l’appel deux fois à filter ou que le tri des données avant le regroupement.
Vérification rapide
Quel est le type de retour de Collectors.partitioningBy(predicate) ?
Récapitulatif : partitioningBy et counting
Points essentiels :
- partitioningBy divise les éléments en exactement deux groupes (true/false)
- Les deux clés sont toujours présentes : aucun risque de NPE, contrairement à groupingBy
- counting() compte les éléments et s’utilise comme collecteur en aval des groupes
- summarizingInt/Long/Double fournit le nombre, la somme, le minimum, le maximum et la moyenne en un seul passage
- Toutes ces opérations s’effectuent en un seul passage du stream, en O(n)
Questions Fréquemment Posées
La leçon « partitioningBy et comptage » est-elle gratuite ?
Oui — le texte complet de « partitioningBy et comptage » 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 « partitioningBy et comptage » ?
Divisez un flux en deux groupes avec partitioningBy et comptez les éléments avec counting. 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 2 sur 4.
Combien de temps prend la leçon « partitioningBy et comptage » ?
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é