如何交错(合并)两个Java 8流? [英] How to interleave (merge) two Java 8 Streams?

查看:215
本文介绍了如何交错(合并)两个Java 8流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 Stream<String> a = Stream.of("one", "three", "five");
 Stream<String> b = Stream.of("two", "four", "six");

要使输出如下,我需要做什么?

What do I need to do for the output to be the below?

// one
// two
// three
// four
// five
// six

我查看了concat,但是正如javadoc解释的那样,它只是一个接一个地追加,它不会交错/散布.

I looked into concat but as the javadoc explains, it just appends one after the other, it does not interleave / intersperse.

Stream<String> out = Stream.concat(a, b);
out.forEach(System.out::println);

创建一个懒散级联的流,其元素均为 第一流的元素,然后是所有元素 第二流.

Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.

错误地给予

 // one
 // three
 // five
 // two
 // four
 // six

如果我收集它们并对其进行迭代,可以这样做,但是希望有更多Java8-y,Streamy:-)

Could do it if I collected them and iterated, but was hoping for something more Java8-y, Streamy :-)

注意

我不想压缩流

"zip"操作将从每个集合中获取一个元素并将其组合.

"zip" operation will take an element from each collection and combine them.

压缩操作的结果如下:(不需要)

the result of a zip operation would be something like this: (unwanted)

 // onetwo
 // threefour
 // fivesix

推荐答案

我会使用类似这样的东西:

I’d use something like this:

public static <T> Stream<T> interleave(Stream<? extends T> a, Stream<? extends T> b) {
    Spliterator<? extends T> spA = a.spliterator(), spB = b.spliterator();
    long s = spA.estimateSize() + spB.estimateSize();
    if(s < 0) s = Long.MAX_VALUE;
    int ch = spA.characteristics() & spB.characteristics()
           & (Spliterator.NONNULL|Spliterator.SIZED);
    ch |= Spliterator.ORDERED;

    return StreamSupport.stream(new Spliterators.AbstractSpliterator<T>(s, ch) {
        Spliterator<? extends T> sp1 = spA, sp2 = spB;

        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            Spliterator<? extends T> sp = sp1;
            if(sp.tryAdvance(action)) {
                sp1 = sp2;
                sp2 = sp;
                return true;
            }
            return sp2.tryAdvance(action);
        }
    }, false);
}

它尽可能地保留了输入流的特性,从而可以进行某些优化(例如count()toArray()).此外,即使输入流可能无序,它也会添加ORDERED来反映交织.

It retains the characteristics of the input streams as far as possible, which allows certain optimizations (e.g. for count()and toArray()). Further, it adds the ORDERED even when the input streams might be unordered, to reflect the interleaving.

当一个流中的元素多于另一个时,其余元素将显示在末尾.

When one stream has more elements than the other, the remaining elements will appear at the end.

这篇关于如何交错(合并)两个Java 8流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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