迭代两个Java-8-Streams

我想将两个Java-8-Streams一起迭代,以便我在每次迭代中都有两个参数。 像这样的东西,其中somefunction产生类似Stream<Pair>

 Stream as; Stream bs; somefunction (as, bs) .forEach ((a, b) -> foo (a, b)); // or something like somefunction (as, bs) .forEach ((Pair abs) -> foo (abs.left (), abs.right ())); 

我想知道,如果Java提供类似的东西,虽然Java中没有Pair :-(如果没有像这样的API函数,是否有另一种方式同时迭代两个流?

 static  Stream> zip(Stream as, Stream bs) { Iterator i=as.iterator(); return bs.filter(x->i.hasNext()).map(b->new Pair<>(i.next(), b)); } 

这不提供并行执行,但原始zip实现也没有。

正如F.Böller指出的那样 ,如果bs是无限的,那么它就不起作用。 对于适用于无限和有限流的所有可能组合的解决方案,在hasNext方法中检查两个源的中间Iterator似乎是不可避免的hasNext

 static  Stream> zip(Stream as, Stream bs) { Iterator i1 = as.iterator(); Iterator i2 = bs.iterator(); Iterable> i=()->new Iterator>() { public boolean hasNext() { return i1.hasNext() && i2.hasNext(); } public Pair next() { return new Pair(i1.next(), i2.next()); } }; return StreamSupport.stream(i.spliterator(), false); } 

如果你想要具有并行function的压缩,你应该考虑Stream来源 。 例如,您可以压缩两个ArrayList (或任何RandomAccessList

 ArrayList l1=new ArrayList<>(); ArrayList l2=new ArrayList<>(); IntStream.range(0, Math.min(l1.size(), l2.size())) .mapToObj(i->new Pair(l1.get(i), l2.get(i))) . … 

¹(除非您直接实施Spliterator