迭代两个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
)