Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)
functional-programming, java-8, java-stream, lambda, lazy-evaluation
Solution
I needed this as well so I just took the source code from b93 and put it in a "util" class. I had to modify it slightly to work with the current API.
For reference here's the working code (take it at your own risk...):
public static<A, B, C> Stream<C> zip(Stream<? extends A> a,
Stream<? extends B> b,
BiFunction<? super A, ? super B, ? extends C> zipper) {
Objects.requireNonNull(zipper);
Spliterator<? extends A> aSpliterator = Objects.requireNonNull(a).spliterator();
Spliterator<? extends B> bSpliterator = Objects.requireNonNull(b).spliterator();
// Zipping loses DISTINCT and SORTED characteristics
int characteristics = aSpliterator.characteristics() & bSpliterator.characteristics() &
~(Spliterator.DISTINCT | Spliterator.SORTED);
long zipSize = ((characteristics & Spliterator.SIZED) != 0)
? Math.min(aSpliterator.getExactSizeIfKnown(), bSpliterator.getExactSizeIfKnown())
: -1;
Iterator<A> aIterator = Spliterators.iterator(aSpliterator);
Iterator<B> bIterator = Spliterators.iterator(bSpliterator);
Iterator<C> cIterator = new Iterator<C>() {
@Override
public boolean hasNext() {
return aIterator.hasNext() && bIterator.hasNext();
}
@Override
public C next() {
return zipper.apply(aIterator.next(), bIterator.next());
}
};
Spliterator<C> split = Spliterators.spliterator(cIterator, zipSize, characteristics);
return (a.isParallel() || b.isParallel())
? StreamSupport.stream(split, true)
: StreamSupport.stream(split, false);
}
Problem
In JDK 8 with lambda b93 there was a class java.util.stream.Streams.zip in b93 which could be used to zip streams (this is illustrated in the tutorial Exploring Java8 Lambdas. Part 1 by Dhananjay Nene). This function : Creates a lazy and sequential combined Stream whose elements are the result of combining the elements of two streams. However in b98 this has disappeared. Infact the `Streams` class is not even accessible in java.util.stream in b98. Has this functionality been moved, and if so how do I zip streams concisely using b98? The application I have in mind is in this java implementation of Shen, where I replaced the zip functionality in the - `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)` functions with rather verbose code (which doesn't use functionality from b98).