0Pricing
Java Academy · Lektion

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 op

counting() 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: 3

In 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));  // 2

Hä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

  1. groupingBy: Elemente klassifizieren
  2. partitioningBy und counting
  3. toMap, joining und summarizing
  4. Einen eigenen Collector erstellen
← Zurück zu Java Academy