W JDK 8 z lambdą b93 istniała klasa java.util.stream.Streams.zip w b93, która mogłaby zostać użyta do zip strumieni (jest to zilustrowane w samouczku Exploring Java8 Lambdas. Part 1 autorstwa Dhananjay Nene ). Ta funkcja:
Tworzy leniwy i sekwencyjny połączony Stream, którego elementy są wynikiem połączenia elementów dwóch strumieni.
Jednak w b98 to zniknęło. W rzeczywistości Streams
klasa nie jest nawet dostępna w java.util.stream w wersji b98 .
Czy ta funkcja została przeniesiona, a jeśli tak, to jak w zwięzły sposób skompresować strumienie za pomocą b98?
Aplikacja, o której myślę, jest w tej implementacji Javy Shen , gdzie zastąpiłem funkcjonalność zip w
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)
funkcje z raczej rozwlekłym kodem (który nie korzysta z funkcjonalności z b98).
Odpowiedzi:
Też tego potrzebowałem, więc po prostu wziąłem kod źródłowy z b93 i umieściłem go w klasie „util”. Musiałem go nieco zmodyfikować, aby działał z obecnym API.
W celach informacyjnych oto działający kod (weź to na własne ryzyko ...):
źródło
SIZED
jeśli jeden ze strumieni toSIZED
nie oba?SIZED
ta implementacja działała, muszą być oba strumienie . W rzeczywistości zależy to od tego, jak zdefiniujesz zamykanie. Czy na przykład powinieneś być w stanie spakować dwa strumienie o różnych rozmiarach? Jak wtedy wyglądałby wynikowy strumień? Uważam, że właśnie dlatego ta funkcja została faktycznie pominięta w API. Można to zrobić na wiele sposobów i od użytkownika zależy, jakie zachowanie powinno być „właściwe”. Czy odrzucić elementy z dłuższego strumienia, czy uzupełnić krótszą listę? Jeśli tak, to jakie wartości?Spliterator<A>
).zip jest jedną z funkcji udostępnianych przez bibliotekę protonpack .
źródło
Jeśli masz guawę w swoim projekcie, możesz użyć metody Streams.zip (została dodana w Guava 21):
źródło
Kompresowanie dwóch strumieni za pomocą JDK8 z lambda ( gist ).
źródło
import java.util.function.*;
iimport java.util.stream.*;
na górze pliku.() -> iterator
i tutaj znowu:iterable.spliterator()
. Dlaczego nie wdrożyć bezpośrednio aSpliterator
zamiast anIterator
? Sprawdź odpowiedź na @Doradus stackoverflow.com/a/46230233/1140754Ponieważ nie mogę sobie wyobrazić zastosowania zapinania na kolekcje inne niż indeksowane (listy) i jestem wielkim fanem prostoty, to byłoby moje rozwiązanie:
źródło
mapToObject
powinnomapToObj
.RandomAccess
(np. na listach zMetody wspomnianej klasy zostały przeniesione do samego
Stream
interfejsu na rzecz metod domyślnych. Ale wydaje się, żezip
metoda została usunięta. Może dlatego, że nie jest jasne, jakie powinno być domyślne zachowanie dla strumieni o różnych rozmiarach. Jednak wdrożenie pożądanego zachowania jest proste:źródło
predicate
przekazany do filtra nie jest stanem ? To narusza kontrakt metody, a zwłaszcza nie zadziała podczas równoległego przetwarzania strumienia.Z pokorą proponuję taką realizację. Wynikowy strumień jest obcinany do krótszego z dwóch strumieni wejściowych.
źródło
.., leftStream.isParallel() || rightStream.isParallel()
. Myślę, że nie ma to żadnego efektu, ponieważAbstractSpliterator
domyślnie oferuje ograniczoną równoległość. Więc myślę, że ostateczny wynik będzie taki sam jak zaliczeniefalse
.Biblioteka Lazy-Seq zapewnia funkcjonalność zip.
https://github.com/nurkiewicz/LazySeq
Ta biblioteka jest mocno zainspirowana
scala.collection.immutable.Stream
i ma na celu zapewnienie niezmiennej, bezpiecznej dla wątków i łatwej w użyciu implementacji leniwych sekwencji, prawdopodobnie nieskończonej.źródło
Korzystając z najnowszej biblioteki Guava (dla
Streams
klasy), powinieneś być w stanie to zrobićźródło
Czy to zadziała dla Ciebie? Jest to krótka funkcja, która leniwie ocenia strumienie, które jest kompresowane, więc możesz dostarczyć jej nieskończoną liczbę strumieni (nie musi brać rozmiaru strumieni, które są skompresowane).
Jeśli strumienie są skończone, zatrzymuje się, gdy tylko w jednym ze strumieni skończą się elementy.
Oto kod testu jednostkowego (znacznie dłuższy niż sam kod!)
źródło
takeWhile
na końcu to, że nie wydaje się być w java8, ale nie stanowi to problemu, ponieważ wywoływany może odfiltrować wszelkie wartości null, które występują, gdy spakowane strumienie nie są tego samego rozmiaru. Myślę, że ta odpowiedź powinna być odpowiedzią numer 1, ponieważ jest spójna i zrozumiała. świetna robota dzięki jeszcze raz.źródło
Cyklop-reakcja AOL , do której się przyczyniam, zapewnia również funkcjonalność kompresowania, zarówno poprzez rozszerzoną implementację Stream , która również implementuje interfejs reaktywnych strumieni ReactiveSeq, jak i za pośrednictwem StreamUtils, który oferuje wiele tych samych funkcji za pośrednictwem metod statycznych do standardowych strumieni Java.
Oferuje również bardziej uogólnione zamykanie oparte na aplikacjach. Na przykład
A nawet możliwość sparowania każdego elementu w jednym strumieniu z każdym elementem w innym
źródło
Jeśli ktoś jeszcze tego potrzebuje,
StreamEx.zipWith
w bibliotece streamex jest funkcja :źródło
To jest świetne. Musiałem spakować dwa strumienie do mapy, przy czym jeden strumień był kluczem, a drugi wartością
Wynik: {A = jabłko, B = banan, C = marchewka}
źródło