How to interleave (merge) two Java 8 Streams?(如何交错(合并)两个 Java 8 流?)
问题描述
流<字符串>a = Stream.of("一", "三", "五");流<字符串>b = Stream.of("二", "四", "六");
我需要做什么才能使输出如下?
//一个//二//三//四个//五//六
我查看了 concat
但正如 javadoc 解释的那样,它只是一个接一个地附加,它不会交错/穿插.
流<字符串>out = Stream.concat(a, b);out.forEach(System.out::println);
<块引用>
创建一个惰性连接流,其元素都是第一个流的元素,然后是第二个流.
错误地给予
//一个//三//五//二//四个//六
如果我收集它们并进行迭代可以做到,但希望有更多的 Java8-y、Streamy :-)
注意
我不想压缩流
<块引用>zip"操作将从每个集合中取出一个元素并将它们组合起来.
zip 操作的结果是这样的:(不需要的)
//onetwo//三四//五六
我会使用这样的:
公共静态<T>流<T>interleave(Stream 扩展 T>a,Stream 扩展 T>b) {分离器动作){分离器
它尽可能地保留了输入流的特征,这允许进行某些优化(例如对于count()
和toArray()
).此外,即使输入流可能是无序的,它也会添加 ORDERED
以反映交错.
当一个流的元素多于另一个时,剩余的元素将出现在最后.
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
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.
Wrongly gives
// one
// three
// five
// two
// four
// six
Could do it if I collected them and iterated, but was hoping for something more Java8-y, Streamy :-)
Note
I don't want to zip the streams
"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);
}
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 流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何交错(合并)两个 Java 8 流?


- Java包名称中单词分隔符的约定是什么? 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01