Java 8: Gute Praxis, um Streams in APIs für verzögerte Operationen weiterzugeben?

12

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/ Mapjedoch 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, Streams 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 Streamist, 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 Collectionund es dann erneut zu wiederholen stream()(und die Kosten für eine eifrige Bewertung zu diesem Zeitpunkt zu bezahlen).

billc.cn
quelle
Was, Guava & Freunde werden nicht aktualisiert, um native Streams zu nutzen?
Kilian Foth
1
Schnittstellen, die Streams aufnehmen und zurückgeben, verbessern die Interoperabilität mit den Standard-Stream-Funktionen. Sie können Anrufe an Ihre Schnittstelle in eine Stream-Pipeline integrieren.
Philipp
@KilianFoth Seit fast einem Jahr gibt es keine Guava-Veröffentlichung mehr und es gibt viele beliebte Artikel darüber, wie man Guavas Lambda-Zeug durch Stream ersetzt. Keiner von ihnen spricht jedoch die Tatsache an, dass Guava-Sammlungsvorgänge eifrig oder faul sein können.
billc.cn

Antworten:

3

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.

Robert Jack Will
quelle