【问题标题】:merge streams to produce alternating sequence using lambda or Stream API使用 lambda 或 Stream API 合并流以生成交替序列
【发布时间】:2018-12-24 02:33:18
【问题描述】:

我有一些代码可以按预期返回 Stream,但也许可以将其替换为某种类型的 lambda 或 stream() 操作,而不是在 while 循环中耗尽迭代器?

这只是一种交替流firstsecond 中的元素并在其中一个元素用完时停止的方法。

public static <T>Stream<T> alternatingSequence(Stream<T> first, Stream<T> second){
        Iterator<T> iteratorFirst = first.iterator();
        Iterator<T> iteratorSecond = second.iterator();
        Stream<T> resultStream = Stream.empty();
        while (iteratorFirst.hasNext() && iteratorSecond.hasNext()){
            resultStream = Stream.concat(resultStream, Stream.of(iteratorFirst.next(), iteratorSecond.next()));
        }
        return resultStream;
    }
}

【问题讨论】:

  • 也许你还包括这段代码应该做的事情,而不是让读者自己弄清楚。
  • 你在交替使用两个迭代器吗?
  • 啊,所以你打算合并两个流 (a1,a2...) 和 (b1,b2...) 并返回 alternating (a1, b1, a2 , b2...) ?并且大概你想要对下一个元素进行惰性评估,对吗?
  • Stream.generate(() -&gt; null).takewhile(iteratorFirst.hasNext() &amp;&amp; iteratorSecond.hasNext()).flatMap(ignored -&gt; Stream.of(iteratorFirst.next(), iteratorSecond.next())) 之类的东西可以,但我认为它并不比您现有的解决方案更具可读性。
  • StreamSupport.stream(iteratorFirst.spliterator(), false).filter(element -&gt; iteratorSecond.hasNext()).flatMap(element -&gt; Stream.of(element, iteratorSecond.next())) 但它再次违反合同,因为Predicate 应该是无状态的。

标签: java java-8 java-stream sequence alternating


【解决方案1】:

使用Guava's Streams.zip,您可以将两个流组合成一个双元素流,然后您可以简单地将其展平以产生交替序列:

return Streams.zip(first, second, (arg1, arg2) -> Stream.of(arg1, arg2))
    .flatMap(Function.identity());

需要注意的是,生成的流不能有效地拆分(请参阅链接文档)。这可能会损害并行性能。

注意:

如果您无法访问 Guava,那么您可以实现自己的 zip(a, b, bifunc),如 here 所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2021-04-11
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多