Ответ 1
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));
}
Это не обеспечивает параллельное выполнение, но и оригинальная реализация zip
.
И как F. Böller отметил, что он не работает, если bs
бесконечен, а as
- нет. Для решения, которое работает для всех возможных комбинаций бесконечных и конечных потоков, промежуточный Iterator
, который проверяет оба источника в методе hasNext
, кажется неизбежным¹:
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);
}
Если вы хотите использовать возможность параллельной записи, вам следует рассмотреть источник Stream
. Например. вы можете закрепить два ArrayList
(или любой RandomAccessList
), например
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)))
. …
¹ (если вы не реализуете непосредственно Spliterator
)