In JDK 8 mit Lambda b93 gab es in b93 eine Klasse java.util.stream.Streams.zip, mit der Streams komprimiert werden konnten (dies wird im Tutorial Exploring Java8 Lambdas. Teil 1 von Dhananjay Nene veranschaulicht ). Diese Funktion:
Erstellt einen faulen und sequentiellen kombinierten Stream, dessen Elemente das Ergebnis der Kombination der Elemente zweier Streams sind.
In b98 ist dies jedoch verschwunden. Tatsächlich ist die Streams
Klasse in bava in java.util.stream nicht einmal zugänglich .
Wurde diese Funktionalität verschoben und wenn ja, wie kann ich Streams mit b98 präzise komprimieren?
Die Anwendung, an die ich denke, befindet sich in dieser Java-Implementierung von Shen , in der ich die Zip-Funktionalität in der ersetzt habe
static <T> boolean every(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
static <T> T find(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
Funktionen mit ziemlich ausführlichem Code (der keine Funktionalität von b98 verwendet).
Antworten:
Ich brauchte das auch, also habe ich einfach den Quellcode von b93 genommen und ihn in eine "util" -Klasse eingeordnet. Ich musste es leicht ändern, um mit der aktuellen API zu arbeiten.
Als Referenz hier ist der Arbeitscode (auf eigenes Risiko ...):
quelle
SIZED
wenn einer der Streams istSIZED
, nicht beide?SIZED
diese Implementierung funktioniert. Es hängt tatsächlich davon ab, wie Sie das Zippen definieren. Sollten Sie beispielsweise zwei Streams unterschiedlicher Größe komprimieren können? Wie würde der resultierende Stream dann aussehen? Ich glaube, aus diesem Grund wurde diese Funktion in der API tatsächlich weggelassen. Es gibt viele Möglichkeiten, dies zu tun, und der Benutzer kann entscheiden, welches Verhalten das "richtige" sein soll. Würden Sie die Elemente aus dem längeren Stream verwerfen oder die kürzere Liste auffüllen? Wenn ja, mit welchen Werten?Spliterator<A>
. B. zu ).zip ist eine der Funktionen der Protonpack-Bibliothek .
quelle
Wenn Sie Guava in Ihrem Projekt haben, können Sie die Streams.zip- Methode verwenden (wurde in Guava 21 hinzugefügt):
quelle
Zippen von zwei Streams mit JDK8 mit Lambda ( Kern ).
quelle
import java.util.function.*;
undimport java.util.stream.*;
oben in Ihrer Datei setzen.() -> iterator
und hier wieder :iterable.spliterator()
. Warum nicht direkt einSpliterator
anstatt ein implementierenIterator
? Überprüfen Sie @Da ich mir keine Verwendung des Zippens für andere als indizierte Sammlungen (Listen) vorstellen kann und ein großer Fan von Einfachheit bin, wäre dies meine Lösung:
quelle
mapToObject
sollte seinmapToObj
.RandomAccess
(z. B. auf verknüpften Listen), ist dies sehr langsamDie Methoden der von Ihnen genannten Klasse wurden
Stream
zugunsten der Standardmethoden in die Schnittstelle selbst verschoben . Aber es scheint, dass diezip
Methode entfernt wurde. Möglicherweise, weil nicht klar ist, wie das Standardverhalten für Streams unterschiedlicher Größe aussehen soll. Die Implementierung des gewünschten Verhaltens ist jedoch unkompliziert:quelle
predicate
Sie an den Filter übergeben haben, nicht zustandsbehaftet ? Dies verstößt gegen den Methodenvertrag und funktioniert insbesondere bei paralleler Verarbeitung des Streams nicht.Ich schlage diese Implementierung demütig vor. Der resultierende Stream wird auf den kürzeren der beiden Eingabestreams abgeschnitten.
quelle
.., leftStream.isParallel() || rightStream.isParallel()
. Ich denke, es hat keine Auswirkung, da esAbstractSpliterator
standardmäßig eine begrenzte Parallelität bietet. Ich denke also, dass das Endergebnis das gleiche sein wird wie das Bestehenfalse
.Die Lazy-Seq-Bibliothek bietet Zip-Funktionen.
https://github.com/nurkiewicz/LazySeq
Diese Bibliothek ist stark inspiriert
scala.collection.immutable.Stream
und zielt darauf ab, eine unveränderliche, threadsichere und einfach zu verwendende Implementierung von verzögerten Sequenzen bereitzustellen, möglicherweise unendlich.quelle
Mit der neuesten Guava-Bibliothek (für die
Streams
Klasse) sollten Sie dazu in der Lage seinquelle
Würde das für dich funktionieren? Es ist eine kurze Funktion, die träge über die zu komprimierenden Streams auswertet, sodass Sie sie mit unendlichen Streams versorgen können (es muss nicht die Größe der zu komprimierenden Streams annehmen).
Wenn die Streams endlich sind, stoppt sie, sobald einem der Streams die Elemente ausgehen.
Hier ist ein Unit-Test-Code (viel länger als der Code selbst!)
quelle
takeWhile
am Ende fallen lassen, das scheint nicht in Java8 zu sein, aber es ist kein Problem, da der Angerufene alle Nullen herausfiltern kann, die auftreten, wenn die komprimierten Streams nicht die gleiche Größe haben. Ich denke, dass diese Antwort die Antwort Nummer 1 sein sollte, da sie konsistent und verständlich ist. Nochmals tolle Arbeit, danke.quelle
Die Cyclops-Reaktion von AOL , zu der ich beitrage, bietet auch Zipping-Funktionen, sowohl über eine erweiterte Stream-Implementierung , die auch die ReactiveSeq-Schnittstelle für reaktive Streams implementiert, als auch über StreamUtils, die Standard-Java-Streams über statische Methoden weitgehend dieselbe Funktionalität bietet.
Es bietet auch allgemeinere anwendungsbezogene Reißverschlüsse. Z.B
Und sogar die Möglichkeit, jedes Element in einem Stream mit jedem Element in einem anderen zu koppeln
quelle
Wenn jemand dies noch braucht, gibt es eine
StreamEx.zipWith
Funktion in der Streamex- Bibliothek:quelle
Das ist toll. Ich musste zwei Streams in eine Map komprimieren, wobei ein Stream der Schlüssel und der andere der Wert war
Ausgabe: {A = Apfel, B = Banane, C = Karotte}
quelle