一起迭代两个 Java-8-Streams

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24059837/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:56:56  来源:igfitidea点击:

Iterate two Java-8-Streams together

javajava-8java-stream

提问by F. B?ller

I'd like to iterate two Java-8-Streams together, so that I have in each iteration-step two arguments. Something like that, where somefunctionproduces something like Stream<Pair<A,B>>.

我想将两个 Java-8-Streams 一起迭代,以便在每个迭代步骤中都有两个参数。类似的东西,在哪里somefunction产生类似的东西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 Pairin Java :-( If there is no API-Function like that, is there another way of iterating two streams simultaniously?

我想知道,如果 Java 提供了类似的东西,尽管PairJava 中没有:-( 如果没有这样的 API-Function,是否有另一种方法可以同时迭代两个流?

采纳答案by Holger

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 zipimplementation.

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

And as F. B?ller has pointed outit doesn't work if bsis infinite and asis not. For a solution which works for all possible combinations of infinite and finite streams, an intermediate Iteratorwhich checks both sources within the hasNextmethod seems unavoidable1:

正如F. B?ller 所指出的那样,如果bs是无限的并且as不是,则它不起作用。对于适用于无限流和有限流的所有可能组合的解决方案,IteratorhasNext方法中检查两个源的中间体似乎是不可避免的1:

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 sourceof the Stream. E.g. you can zip two ArrayLists (or any RandomAccessList) like

如果您希望能够平行您的压缩和解应该考虑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)))
         . …


1(unless you implement a Spliteratordirectly)

1(除非你Spliterator直接实现)