Iterate two Java-8-Streams together
java, java-8, java-stream
Solution
static <A, B> Stream<Pair<A, B>> zip(Stream<A> as, Stream<B> bs)
{
Iterator<A> i=as.iterator();
return bs.filter(x->i.hasNext()).map(b->new Pair<>(i.next(), b));
}
This does not offer parallel execution but neither did the original `zip` implementation.
And as F. Böller has pointed out it doesn’t work if `bs` is infinite and `as` is not. For a solution which works for all possible combinations of infinite and finite streams, an intermediate `Iterator` which checks both sources within the `hasNext` method seems unavoidable¹:
static <A, B> Stream<Pair<A,B>> zip(Stream<A> as, Stream<B> bs) {
Iterator<A> i1 = as.iterator();
Iterator<B> i2 = bs.iterator();
Iterable<Pair<A,B>> i=()->new Iterator<Pair<A,B>>() {
public boolean hasNext() {
return i1.hasNext() && i2.hasNext();
}
public Pair<A,B> next() {
return new Pair<A,B>(i1.next(), i2.next());
}
};
return StreamSupport.stream(i.spliterator(), false);
}
If you want parallel capable zipping you should consider the source of the `Stream`. E.g. you can zip two `ArrayList`s (or any `RandomAccessList`) like
ArrayList<Foo> l1=new ArrayList<>();
ArrayList<Bar> l2=new ArrayList<>();
IntStream.range(0, Math.min(l1.size(), l2.size()))
.mapToObj(i->new Pair(l1.get(i), l2.get(i)))
. …
¹(unless you implement a `Spliterator` directly)
Problem
I'd like to iterate two Java-8-Streams together, so that I have in each iteration-step two arguments. Something like that, where `somefunction` produces something like `Stream<Pair<A,B>>`. ``` Stream<A> as; Stream<B> bs; somefunction (as, bs) .forEach ((a, b) -> foo (a, b)); // or something like somefunction (as, bs) .forEach ((Pair<A, B> abs) -> foo (abs.left (), abs.right ())); ``` I want to know, if Java provides something like that, although there is no `Pair` in Java :-( If there is no API-Function like that, is there another way of iterating two streams simultaniously?