Geschichte der Frage:
Die Stream API wurde in Java 8 hinzugefügt, um funktionale Programmierung und parallele Verarbeitung von Sammlungen zu erleichtern. Sie bietet eine bequeme Möglichkeit, Ketten von Operationen auf Daten durch Lambda-Ausdrücke zu beschreiben.
Problem:
Ohne die Stream API musste man umfangreichen imperativen Code für das Filtern, Sortieren und Aggregieren von Sammlungen schreiben. Potenzial für Fehler, Komplexität der Wartung, Ineffizienz beim Versuch, Parallelität manuell hinzuzufügen.
Lösung:
Die Stream API ermöglicht den Aufbau einer Pipeline aus Zwischenoperationen (intermediate) und Terminaloperationen (terminal). Streams sind lazy, arbeiten sequentiell oder parallel mit Daten, der Code wird kompakter und ausdrucksvoller.
Beispiel für die Verarbeitung einer Sammlung:
List<String> names = Arrays.asList("Anna", "Ivan", "Petr", "Eva"); names.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .forEach(System.out::println);
Schlüsselfunktionen:
parallelStream()), muss aber die Thread-Sicherheit von Sammlungen und Funktionen beachten.Kann man denselben Stream nach seinem Schließen wiederverwenden?
Nein, der Versuch, einen geschlossenen Stream erneut zu verwenden, wirft eine IllegalStateException. Ein Stream ist einmalig.
Beeinflusst eine Änderung der ursprünglichen Sammlung nach der Erstellung des Streams?
Ja, wenn die Sammlung nach der Erstellung des Streams, aber vor der Terminaloperation geändert wird, sind ConcurrentModificationExceptions möglich.
Kann man externe veränderbare Variablen innerhalb von Stream-Operationen verwenden?
Es wird nicht empfohlen, da dies in einem parallelen Stream zu unerwarteten Fehlern führt. Es ist besser, mutierbare Seiteneffekte im Stream-Pipeline zu vermeiden.
.parallelStream() auf nicht threadsichere SammlungenEin Programmierer ruft über einen Stream eine Methode auf, die die externe Liste ändert — dies funktioniert bei sequenzieller Ausführung, führt jedoch bei paralleler Ausführung zu einer Störung der Datenstruktur.
Vorteile:
Nachteile:
Die gesamte Pipeline wird sauber aufgebaut: Operationen haben keine Seiteneffekte, es werden nur unveränderliche Sammlungen verwendet, das endgültige Ergebnis wird über einen Collector gesammelt.
Vorteile:
Nachteile: