diff --git a/docs/documentation/java-stream-api.md b/docs/documentation/java-stream-api.md index c038993aa3..223a1f41db 100644 --- a/docs/documentation/java-stream-api.md +++ b/docs/documentation/java-stream-api.md @@ -98,10 +98,13 @@ intermediäre Operationen sind Filtern, Abbilden und Sortieren. | Abbilden | `IntStream mapToInt(mapper: ToIntFunction)` | `int applyAsInt(value: T)` | | Abbilden | `LongStream mapToLong(mapper: ToLongFunction)` | `long applyAsLong(value: T)` | | Spähen | `Stream peek(consumer: Consumer)` | `void accept(t: T)` | +| Abflachen | `Stream flatMap(mapper: Function>)` | `R apply(t: T)` | | Sortieren | `Stream sorted(comparator: Comparator)` | `int compare(o1: T, o2: T)` | +| Sortieren | `Stream sorted()` | - | | Unterscheiden | `Stream distinct()` | - | | Begrenzen | `Stream limit(maxSize: long)` | - | | Überspringen | `Stream skip(n: long)` | - | +| Sammeln | `List toList()` | - | ## Terminale Operationen @@ -126,6 +129,72 @@ Elementen. Zahlenströme (`IntStream`, `DoubleStream`, `LongStream`) bieten zusätzlich die terminalen Operationen `sum()` und `average()`. +## Collectors + +Die terminale Operation `collect()` nimmt einen `Collector` entgegen und fasst +die Elemente des Stroms zu einem Ergebnis zusammen. Die Klasse `Collectors` +(Paket `java.util.stream`) stellt fertige Collector-Implementierungen für die +häufigsten Anwendungsfälle bereit. + +| Collector | Methode | Beschreibung | +| ---------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | +| In Liste sammeln | `toList()` | Sammelt Elemente in eine `List` | +| In Menge sammeln | `toSet()` | Sammelt Elemente in eine `Set` (Duplikate werden entfernt) | +| In Map sammeln | `toMap(keyMapper: Function, valueMapper: Function)` | Sammelt Elemente in eine `Map` | +| Gruppieren | `groupingBy(classifier: Function)` | Gruppiert Elemente nach Schlüssel in eine `Map>` | +| Gruppieren | `groupingBy(classifier: Function, downstream: Collector)` | Gruppiert und wendet auf jede Gruppe einen weiteren Collector an | +| Partitionieren | `partitioningBy(predicate: Predicate)` | Teilt Elemente in zwei Gruppen (`true`/`false`) auf | +| Partitionieren | `partitioningBy(predicate: Predicate, downstream: Collector)` | Partitioniert und wendet auf jede Partition einen weiteren Collector an | +| Abbilden | `mapping(mapper: Function, downstream: Collector)` | Bildet Elemente ab, bevor ein nachgelagerter Collector sie sammelt | +| Zählen | `counting()` | Zählt die Elemente (nützlich als nachgelagerter Collector) | +| Verbinden | `joining()` | Verbindet `String`-Elemente zu einem einzigen String | +| Verbinden | `joining(delimiter: CharSequence)` | Verbindet Elemente mit einem Trennzeichen | +| Verbinden | `joining(delimiter: CharSequence, prefix: CharSequence, suffix: CharSequence)` | Verbindet Elemente mit Trennzeichen, Präfix und Suffix | +| Summieren | `summingInt(mapper: ToIntFunction)` | Berechnet die Summe der gemappten `int`-Werte | +| Summieren | `summingDouble(mapper: ToDoubleFunction)` | Berechnet die Summe der gemappten `double`-Werte | +| Summieren | `summingLong(mapper: ToLongFunction)` | Berechnet die Summe der gemappten `long`-Werte | +| Durchschnitt | `averagingInt(mapper: ToIntFunction)` | Berechnet den Durchschnitt der gemappten `int`-Werte als `double` | +| Durchschnitt | `averagingDouble(mapper: ToDoubleFunction)` | Berechnet den Durchschnitt der gemappten `double`-Werte | +| Durchschnitt | `averagingLong(mapper: ToLongFunction)` | Berechnet den Durchschnitt der gemappten `long`-Werte als `double` | +| Zusammenfassen | `summarizingInt(mapper: ToIntFunction)` | Liefert Statistiken (Anzahl, Summe, Min, Max, Durchschnitt) als `IntSummaryStatistics` | + +Das folgende Beispiel zeigt typische Anwendungen von `Collectors`: + +```java title="MainClass.java" showLineNumbers +public class MainClass { + + record Person(String name, String city) {} + + public static void main(String[] args) { + List persons = List.of( + new Person("Anna", "Berlin"), + new Person("Ben", "Hamburg"), + new Person("Clara", "Berlin"), + new Person("David", "Hamburg"), + new Person("Eva", "Berlin") + ); + + // Alle Namen als kommaseparierten String zusammenfassen + String names = persons.stream() + .map(Person::name) + .collect(Collectors.joining(", ")); + + // Personen nach Stadt gruppieren + Map> byCity = persons.stream() + .collect(Collectors.groupingBy(Person::city)); + + // Anzahl der Personen je Stadt + Map countByCity = persons.stream() + .collect(Collectors.groupingBy(Person::city, Collectors.counting())); + + // Personen nach Wohnort Berlin / nicht Berlin aufteilen + Map> partitioned = persons.stream() + .collect(Collectors.partitioningBy(p -> p.city().equals("Berlin"))); + } + +} +``` + ## Bedarfsauswertung (Lazy Evaluation) Bei der Bedarfsauswertung werden intermediäre Operationen nicht sofort