当前位置: 首页 > 知识库问答 >
问题:

如何交织(合并)两个Java 8流?

禄俊逸
2023-03-14
 Stream<String> a = Stream.of("one", "three", "five");
 Stream<String> b = Stream.of("two", "four", "six");

我需要做什么才能使输出如下所示?

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

我查看了concat,但正如javadoc所解释的,它只是一个接一个地附加,而不是交错/穿插。

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

创建一个延迟连接的流,其元素是第一个流的所有元素,然后是第二个流的所有元素。

错误地给予

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

如果我收集它们并迭代,可以做到这一点,但希望有更多的Java8-y,Streamy:-)

笔记

我不想让溪流断流

“zip”操作将从每个集合中获取一个元素并将其组合。

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

 // onetwo
 // threefour
 // fivesix

共有3个答案

何长恨
2023-03-14

正如您从问题评论中看到的,我使用zip进行了尝试:

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

Stream<String> out = interleave(a, b);


    public static <T> Stream<T> interleave(Stream<T> streamA, Stream<T> streamB) {
        return zip(streamA, streamB, (o1, o2) -> Stream.of(o1, o2)).flatMap(s -> s);
    }

    /**
    * https://stackoverflow.com/questions/17640754/zipping-streams-using-jdk8-with-lambda-java-util-stream-streams-zip
    **/
    private static <A, B, C> Stream<C> zip(Stream<A> streamA, Stream<B> streamB, BiFunction<A, B, C> zipper) {
        final Iterator<A> iteratorA = streamA.iterator();
        final Iterator<B> iteratorB = streamB.iterator();
        final Iterator<C> iteratorC = new Iterator<C>() {
            @Override
            public boolean hasNext() {
                return iteratorA.hasNext() && iteratorB.hasNext();
            }

            @Override
            public C next() {
                return zipper.apply(iteratorA.next(), iteratorB.next());
            }
        };
        final boolean parallel = streamA.isParallel() || streamB.isParallel();
        return iteratorToFiniteStream(iteratorC, parallel);
    }

    private static <T> Stream<T> iteratorToFiniteStream(Iterator<T> iterator, boolean parallel) {
        final Iterable<T> iterable = () -> iterator;
        return StreamSupport.stream(iterable.spliterator(), parallel);
    }
岳景明
2023-03-14

这是一个比霍尔格更愚蠢的解决方案,但可能符合你的要求:

private static <T> Stream<T> interleave(Stream<T> left, Stream<T> right) {
    Spliterator<T> splLeft = left.spliterator();
    Spliterator<T> splRight = right.spliterator();

    T[] single = (T[]) new Object[1];

    Stream.Builder<T> builder = Stream.builder();

    while (splRight.tryAdvance(x -> single[0] = x) && splLeft.tryAdvance(builder)) {
        builder.add(single[0]);
    }

    return builder.build();
}
司徒俊雄
2023-03-14

我会用这样的东西:

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以反映交错。

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

 类似资料:
  • 问题内容: 对于下面的输出,我需要做什么? 我调查了一下,但是正如javadoc所解释的,它只是一个接一个地追加,它不会交错/散布。 创建一个延迟串联的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 错误地给 如果我收集它们并进行迭代,但是希望获得更多Java8-y,Streamy :-),可以这样做 注意 我不想压缩流 “ zip”操作将从每个集合中获取一个元素并将其组合。 压缩操作的

  • 我有两个(或更多)

  • 问题内容: 我有第一个json: 第二个: 我想合并/合并两个数据数组,例如: (我现在不在乎)。 如何快速简便地做到这一点?这是我的尝试: 但是会引发异常: 问题答案: JArray dataOfJson1=json1.SelectToken(“data”);

  • 问题内容: 如何合并结构相同的两个MySQL表? 这两个表的主键将发生冲突,因此我考虑了这一点。 问题答案: 您也可以尝试: 这允许table_1中的行取代table_2中具有匹配主键的行,同时仍插入具有新主键的行。 或者, 将使用来自表_2的相应行更新表_1中已经存在的行,同时插入具有新主键的行。

  • 我有一个Java类,它有20个属性及其相应的getter和setter。还有两个对象列表:和。 使用Java 8: 但是我必须在哪个地方指定属性呢?是否应该重写和方法?

  • 我有两个xml文件,需要将它们合并为一个xml。以下是示例: orginal.xml文件: 使现代化xml文件: 它们应合并为如下xml文件: 实际上,我想使用更新。xml来更新原始。xml: > update.xml中的新员工应该被添加到original.xml 在更新中修改了员工信息。xml应覆盖相应的员工节点。 我对XSLT略知一二,但我的知识还不足以找出适合合并的XSLT。