In Lambda-lastigen Bibliotheken vor Java 8 wie Guava verwenden die Ausgaben gängige Java Collection Framework-Schnittstellen, sodass sie leicht an externe / interne APIs weitergegeben werden können und dennoch einige verzögerte Berechnungen möglich sind, wenn die Bibliotheksmethode dies tut (z . B. faul filter()
und transform()
).
In Java 8-Streams ist der Aufruf zum Abrufen eines Collection
/ Map
jedoch ein Terminal (dh eifrig), und es werden auch neue Datenstrukturen zugewiesen, um die Ergebnisse zu speichern.
Bei komplizierten Berechnungen mit mehreren Stufen und Strategiemustern in der Mitte führt dies aufgrund der Zwischenergebnisse zu vielen unnötigen Zuordnungen.
Glauben die Leute, dass es eine gute Praxis für interne APIs (dh Strategiemusterstrategien) ist, Stream
s zu übernehmen und zurückzugeben, oder sollte ich einfach auf die faulen, aber nicht optimierten (Wortspiel beabsichtigt, denke ich) Guava-APIs zurückgreifen?
Bearbeiten:
Mein Hauptanliegen Stream
ist, dass es nur einmal konsumiert werden kann und so etwas wie ein Supplier<Stream<X>>
äußerst umständliches Aussehen passiert . Es drängt Sie fast dazu, nur ein zu bestehen Collection
und es dann erneut zu wiederholen stream()
(und die Kosten für eine eifrige Bewertung zu diesem Zeitpunkt zu bezahlen).
Antworten:
Laziness in Java 8 Streams funktioniert genauso wie früher für Iterables in Guava: Sie müssen das Iterable weitergeben, um faul zu bleiben, und die Auswertung erfolgt, sobald Sie eine Sammlung aus dem Iterator erstellt haben. Sowohl Streams als auch Iteratoren können nur einmal verwendet werden.
Für Ihre Methodenschnittstellen besteht die allgemeinere Methode (die Faulheit zulässt) darin, die Stream-Schnittstelle zu verwenden (wann immer Sie zuvor Iterable verwendet hätten). Wie @Philipp sagt, können sie damit in Stream-Pipelines verwendet werden.
Da Stream jetzt eine offizielle Java-Standardschnittstelle ist, wird es hoffentlich immer mehr andere Bibliotheken und Funktionen geben, die effizient direkt mit Streams arbeiten können.
quelle