迭代两个Java-8-Streams [英] Iterate two Java-8-Streams together

查看:85
本文介绍了迭代两个Java-8-Streams的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 ()));

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

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?

推荐答案

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 实现也没有。

This does not offer parallel execution but neither did the original zip implementation.

并且F.Böller指出如果<$ < c $ c> bs 是无限的,不是。对于适用于所有可能的梳子的解决方案无限和有限流的inations,中间 Iterator 检查 hasNext 方法中的两个来源似乎是不可避免的¹:

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);
}

如果你想要具有并行功能的压缩,你应该考虑 of Stream 。例如。你可以压缩两个 ArrayList s(或任何 RandomAccessList ),如

If you want parallel capable zipping you should consider the source of the Stream. E.g. you can zip two ArrayLists (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)))
         . …






¹(除非你实施 Spliterator 直接)

这篇关于迭代两个Java-8-Streams的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆