partitioningBy und counting
Teilen Sie einen Stream mit partitioningBy in zwei Gruppen auf und zählen Sie Elemente mit counting.
partitioningBy und counting ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Grundlagen von partitioningBy
Collectors.partitioningBy(predicate) teilt einen Stream in genau zwei Gruppen auf – true und false – und gibt eine Map<Boolean, List<T>> zurück.
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 im Vergleich zu filter
Im Gegensatz zu filter behält partitioningBy beide Gruppen gleichzeitig bei – nützlich, wenn Sie beide Teile der Aufteilung benötigen.
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());Nachgelagerter Collector mit partitioningBy
Kombinieren Sie partitioningBy genauso wie groupingBy mit einem nachgelagerten Collector:
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));Der counting()-Collector
Collectors.counting() zählt die Anzahl der Elemente im Stream oder in der nachgelagerten Gruppe. Er ist eine komfortable Entsprechung zu 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() als nachgelagerter Collector
counting() spielt seine Stärke als nachgelagerter Collector für groupingBy/partitioningBy aus:
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: 3In Namen aufteilen
Extrahieren Sie die Namen aus jeder Teilgruppe, indem Sie einen nachgelagerten mapping-Collector verwenden:
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));counting mit summarizingInt kombinieren
Collectors.summarizingInt() berechnet Anzahl, Summe, Minimum, Maximum und Durchschnitt in einem Durchlauf:
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());Praxisbeispiel: A/B-Testaufteilung
Teilen Sie Benutzer für einen A/B-Test in Kontroll- und Behandlungsgruppen auf:
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)); // 2Häufigkeits-Map mit groupingBy + counting
Zählen Sie, wie oft jedes Element vorkommt (Wortfrequenz-Map):
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 gibt immer beide Schlüssel zurück
Im Gegensatz zu groupingBy gibt partitioningBy immer eine Map mit den Schlüsseln true und false zurück – auch wenn eine Gruppe leer ist. Dadurch werden NullPointerExceptions bei map.get(true) vermieden.
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]Performance: Ein Durchlauf
Sowohl partitioningBy als auch counting arbeiten in einem einzigen Stream-Durchlauf – O(n). Sie benötigen keine Sortierung. Dadurch sind sie deutlich effizienter, als filter zweimal aufzurufen oder vor dem Gruppieren zu sortieren.
Kurze Überprüfung
Welcher Rückgabetyp wird von Collectors.partitioningBy(predicate) verwendet?
Rückblick: partitioningBy und counting
Die wichtigsten Punkte:
- partitioningBy teilt in genau zwei Gruppen auf (true/false)
- Beide Schlüssel sind immer vorhanden – kein NPE-Risiko wie bei groupingBy
- counting() zählt Elemente und kann als nachgelagerter Collector für Gruppen verwendet werden
- summarizingInt/Long/Double liefert Anzahl, Summe, Minimum, Maximum und Durchschnitt in einem Durchlauf
- Alle arbeiten in einem einzigen O(n)-Stream-Durchlauf
Häufig gestellte Fragen
Ist die Lektion „partitioningBy und counting“ kostenlos?
Ja — der vollständige Text von „partitioningBy und counting“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „partitioningBy und counting“?
Teilen Sie einen Stream mit partitioningBy in zwei Gruppen auf und zählen Sie Elemente mit counting. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „partitioningBy und counting“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- groupingBy: Elemente klassifizieren
- partitioningBy und counting
- toMap, joining und summarizing
- Einen eigenen Collector erstellen