toMap, joining und summarizing
Wandeln Sie Streams in Maps um, verketten Sie Strings mit joining und berechnen Sie Statistiken mit summarizingInt.
toMap, joining und summarizing ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 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 Collectors.toMap
Collectors.toMap(keyMapper, valueMapper) wandelt einen Stream in eine Map um. Jedes Element liefert ein Schlüssel-Wert-Paar.
import java.util.*;
import java.util.stream.*;
record Country(String code, String name) {}
List<Country> countries = List.of(
new Country("US","United States"),
new Country("DE","Germany"),
new Country("JP","Japan")
);
Map<String, String> codeToName =
countries.stream().collect(
Collectors.toMap(Country::code, Country::name)
);
System.out.println(codeToName.get("DE")); // GermanyDoppelte Schlüssel behandeln
toMap löst bei doppelten Schlüsseln eine IllegalStateException aus. Übergeben Sie als drittes Argument eine Merge-Funktion, um Konflikte aufzulösen:
List<String> words = List.of("apple","ant","banana","bat","cherry");
Map<Character, String> firstByLetter =
words.stream().collect(
Collectors.toMap(
w -> w.charAt(0),
w -> w,
(existing, replacement) -> existing // keep first
)
);
System.out.println(firstByLetter); // {a=apple, b=banana, c=cherry}toMap mit Wertumwandlung
Der valueMapper kann jede beliebige Funktion sein – wandeln Sie das Element vor dem Speichern um:
record User(String login, String email) {}
List<User> users = List.of(
new User("alice","alice@example.com"),
new User("bob","bob@example.com")
);
Map<String, String> loginToEmail =
users.stream().collect(
Collectors.toMap(User::login, u -> u.email().toUpperCase())
);
System.out.println(loginToEmail.get("alice")); // ALICE@EXAMPLE.COMtoUnmodifiableMap
Verwenden Sie Collectors.toUnmodifiableMap(), um eine unveränderliche Map zu erzeugen – dies entspricht dem Umhüllen mit Collections.unmodifiableMap(), ist aber übersichtlicher:
Map<String, Integer> wordLengths =
Stream.of("Java","Stream","API")
.collect(Collectors.toUnmodifiableMap(w -> w, String::length));
// wordLengths.put("test",4); // throws UnsupportedOperationExceptionCollectors.joining
Collectors.joining() verkettet Zeichenkettenelemente. Optional können Sie ein Trennzeichen, ein Präfix und ein Suffix angeben:
List<String> names = List.of("Alice","Bob","Carol");
System.out.println(names.stream().collect(Collectors.joining()));
// AliceBobCarol
System.out.println(names.stream().collect(Collectors.joining(", ")));
// Alice, Bob, Carol
System.out.println(names.stream().collect(Collectors.joining(", ", "[", "]")));
// [Alice, Bob, Carol]joining für CSV-Ausgaben
Erstellen Sie mit joining CSV-Zeilen oder SQL-IN-Klauseln:
List<Integer> ids = List.of(1,2,3,4,5);
String inClause = ids.stream()
.map(Object::toString)
.collect(Collectors.joining(",", "(", ")"));
System.out.println("WHERE id IN " + inClause);
// WHERE id IN (1,2,3,4,5)summarizingInt / Long / Double
Collectors.summarizingInt() berechnet alle Statistiken in einem Durchlauf und gibt eine IntSummaryStatistics zurück:
record Product(String name, int price) {}
List<Product> products = List.of(
new Product("A",100), new Product("B",200), new Product("C",150)
);
IntSummaryStatistics stats =
products.stream().collect(Collectors.summarizingInt(Product::price));
System.out.println("Count: " + stats.getCount()); // 3
System.out.println("Sum: " + stats.getSum()); // 450
System.out.println("Min: " + stats.getMin()); // 100
System.out.println("Max: " + stats.getMax()); // 200
System.out.println("Avg: " + stats.getAverage()); // 150.0summingInt und averagingInt
Für einfachere Fälle, in denen Sie nur eine Statistik benötigen:
int total = products.stream().collect(Collectors.summingInt(Product::price));
System.out.println("Total: " + total); // 450
double avg = products.stream().collect(Collectors.averagingInt(Product::price));
System.out.println("Average: " + avg); // 150.0groupingBy mit summarizingInt
Kombinieren Sie die Zusammenfassung für jede Gruppe:
record Sale(String region, int amount) {}
List<Sale> sales = List.of(
new Sale("North",100), new Sale("South",200),
new Sale("North",150), new Sale("South",300)
);
Map<String, IntSummaryStatistics> statsByRegion =
sales.stream().collect(
Collectors.groupingBy(Sale::region,
Collectors.summarizingInt(Sale::amount))
);
statsByRegion.forEach((r,s) ->
System.out.printf("%s: sum=%d avg=%.1f%n", r, s.getSum(), s.getAverage()));Sammeln in eine LinkedHashMap
Standardmäßig erzeugt toMap eine HashMap ohne festgelegte Reihenfolge. Verwenden Sie die Überladung mit vier Argumenten, um eine LinkedHashMap zur Bewahrung der Einfügereihenfolge anzugeben:
Map<String, Integer> ordered =
Stream.of("banana","apple","cherry")
.collect(Collectors.toMap(
w -> w,
String::length,
(a,b) -> a,
LinkedHashMap::new
));
System.out.println(ordered.keySet()); // [banana, apple, cherry]Praxis: Konfigurationsparser
Parsen Sie Zeilen im Format key=value mit toMap in eine Map:
List<String> lines = List.of("host=localhost","port=5432","db=myapp");
Map<String, String> config =
lines.stream()
.map(l -> l.split("=", 2))
.collect(Collectors.toMap(a -> a[0], a -> a[1]));
System.out.println(config.get("port")); // 5432Kurze Überprüfung
Sie verwenden Collectors.toMap(k, v) für einen Stream, der zwei Elemente mit demselben Schlüssel enthält. Was geschieht?
Rückblick: toMap, joining und summarizing
Die wichtigsten Punkte:
- toMap(keyMapper, valueMapper) – löst ohne Merge-Funktion bei doppelten Schlüsseln eine Ausnahme aus
- joining(delimiter, prefix, suffix) – verkettet Zeichenketten auf elegante Weise
- summarizingInt liefert Anzahl, Summe, Minimum, Maximum und Durchschnitt in einem Durchlauf
- summingInt/averagingInt für Fälle, in denen nur eine Statistik benötigt wird
- Verwenden Sie toMap mit vier Argumenten und LinkedHashMap::new für Ergebnisse mit festgelegter Reihenfolge
Häufig gestellte Fragen
Ist die Lektion „toMap, joining und summarizing“ kostenlos?
Ja — der vollständige Text von „toMap, joining und summarizing“ 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 „toMap, joining und summarizing“?
Wandeln Sie Streams in Maps um, verketten Sie Strings mit joining und berechnen Sie Statistiken mit summarizingInt. 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 3 von 4.
Wie lange dauert die Lektion „toMap, joining und summarizing“?
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