0Pricing
Java Academy · Lektion

groupingBy: Elemente klassifizieren

Gruppieren Sie Stream-Elemente anhand einer Klassifizierungsfunktion in Maps und kombinieren Sie sie mit nachgelagerten Collectors.

groupingBy: Elemente klassifizieren ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 1 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.

Was ist groupingBy?

Collectors.groupingBy() teilt Stream-Elemente in eine Map auf, in der jeder Schlüssel auf eine Liste der passenden Elemente verweist. Dies entspricht dem GROUP BY in SQL.

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()));

Nachgelagerter Collector: counting

Kombinieren Sie groupingBy mit einem nachgelagerten Collector, um zu aggregieren, statt Elemente aufzulisten:

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

Nachgelagerter Collector: mapping

Verwenden Sie Collectors.mapping() als nachgelagerten Collector, um Elemente vor dem Sammeln umzuwandeln:

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));

Nachgelagerter Collector: joining

Verketten Sie die Namen jeder Gruppe zu einer einzigen, durch Kommas getrennten Zeichenkette:

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

Mehrstufiges groupingBy

Verschachteln Sie mehrere groupingBy-Aufrufe für eine mehrdimensionale Klassifizierung:

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())));

Map-Typ festlegen

Standardmäßig erzeugt groupingBy eine HashMap. Verwenden Sie die Überladung mit drei Argumenten, um einen anderen Map-Typ anzugeben, etwa TreeMap für sortierte Schlüssel:

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

Nachgelagert: averagingInt

Berechnen Sie die Durchschnittswerte für jede Gruppe:

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));

Nachgelagert: toUnmodifiableList

Verwenden Sie Collectors.toUnmodifiableList() als nachgelagerten Collector, um unveränderliche Gruppen zu erzeugen:

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

Praxisbeispiel: Bestellübersicht

Gruppieren Sie Bestellungen nach Status und summieren Sie die Beträge jeder Gruppe:

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));

Überlegungen zur Performance

groupingBy speichert alle Elemente im Arbeitsspeicher. Bei sehr großen Datenmengen sollten Sie die Verarbeitung in Blöcken oder ein GROUP BY auf Datenbankebene in Betracht ziehen. Der nachgelagerte Collector wird für jedes Element ausgeführt – halten Sie ihn schlank, um ein Verhalten mit O(n²) zu vermeiden.

Kombination mit filter und sorted

Verketten Sie Stream-Operationen vor dem Sammeln, um Daten vorab zu filtern oder zu sortieren:

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}

Kurze Überprüfung

Welchen Typ erzeugt Collectors.groupingBy(Person::city), wenn es mit collect() verwendet wird?

Rückblick: groupingBy

Die wichtigsten Punkte:

  • groupingBy(classifier) → Map<K, List<T>>
  • Kombinieren Sie groupingBy mit nachgelagerten Collectors: counting, mapping, joining und summarizing
  • Verschachteln Sie groupingBy für eine mehrdimensionale Klassifizierung
  • Verwenden Sie die Überladung mit drei Argumenten, um den resultierenden Map-Typ zu steuern, z. B. TreeMap

Häufig gestellte Fragen

Ist die Lektion „groupingBy: Elemente klassifizieren“ kostenlos?

Ja — der vollständige Text von „groupingBy: Elemente klassifizieren“ 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 „groupingBy: Elemente klassifizieren“?

Gruppieren Sie Stream-Elemente anhand einer Klassifizierungsfunktion in Maps und kombinieren Sie sie mit nachgelagerten Collectors. 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 1 von 4.

Wie lange dauert die Lektion „groupingBy: Elemente klassifizieren“?

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