Java Streams (Stream-API)
Kurz: Die Stream-API (seit Java 8) verarbeitet Datenmengen als „Fließband”: Aus einer Quelle wie einer Liste entsteht ein Stream, auf den man Schritte wie filtern, umwandeln und sammeln anwendet. Streams sind etwas anderes als die I/O-Streams für Dateien.
Genauer: Statt Schleifen mit Zwischenvariablen beschreibt man, was passieren soll (deklarativ). Ein Stream speichert keine Daten, er ist eine Beschreibung der Verarbeitung. Die Arbeit geschieht erst, wenn eine Endoperation aufgerufen wird („lazy”).
Im Detail
List<String> namen = List.of("Anna", "Ben", "Cem", "Amelie", "Anton");
List<String> ergebnis = namen.stream() // Quelle
.filter(n -> n.startsWith("A")) // Zwischenoperation: auswählen
.map(String::toUpperCase) // Zwischenoperation: umwandeln
.sorted() // Zwischenoperation: sortieren
.collect(Collectors.toList()); // Endoperation: einsammeln
// [AMELIE, ANNA, ANTON]
int summe = IntStream.rangeClosed(1, 100).sum(); // 5050
double schnitt = namen.stream().mapToInt(String::length).average().orElse(0);
Map<Integer, List<String>> nachLaenge = namen.stream().collect(Collectors.groupingBy(String::length));Aufbau einer Pipeline: Quelle → Zwischenoperationen (liefern wieder einen Stream) → eine Endoperation.
| Art | Beispiele |
|---|---|
| Quelle | list.stream(), Arrays.stream(a), Stream.of(...), IntStream.range(...), Files.lines(path) |
| Zwischenoperationen | filter, map, flatMap, sorted, distinct, limit, skip, peek |
| Endoperationen | collect, forEach, reduce, count, sum, min, max, anyMatch, findFirst, toList() |
- Lazy: Ohne Endoperation passiert nichts.
limit(3)stoppt, sobald drei Treffer da sind. - Einmal benutzbar: Ein Stream lässt sich nur einmal verarbeiten, danach
IllegalStateException. - Original unverändert: Streams ändern die Quelle nicht. Das Ergebnis ist eine neue Sammlung.
- Parallel:
parallelStream()verteilt die Arbeit auf mehrere Kerne. Nur bei großen Mengen und ohne Seiteneffekte sinnvoll, sonst oft langsamer. - Primitive Streams:
IntStream,LongStream,DoubleStreamvermeiden das Boxing und bietensum(),average(). - Keine Seiteneffekte: In
mapundfilterkeine Variablen von außen verändern. - Lesbarkeit: Lange Ketten werden unübersichtlich. Dann in benannte Methoden auslagern oder eine normale Schleife nehmen.
Siehe auch: Lambda, Java: Lambdas und Streams, Iterieren