java - 如何交错(合并)两个 Java 8 流?
问题描述
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
解决方案
我会使用这样的东西:
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);
}
它尽可能地保留输入流的特征,从而允许进行某些优化(例如 forcount()
和toArray()
)。此外,它ORDERED
甚至在输入流可能是无序的情况下添加,以反映交错。
当一个流的元素多于另一个时,剩余的元素将出现在最后。
推荐阅读
- ssis - ole db 适配器使用的 ole db 提供程序无法在 SSIS 中的类型 dt_dbtimestamp 和 dt_numeric 之间转换
- javascript - Discord Bot:使用 Node.js 添加基于 user_id 的角色
- excel - Pilcrow ¶ - CONCATENATE Char(10) 与数字时发生?
- r - R中的堆积面积图
- swift - 在@available 属性中参数化消息
- sass - Sass lightness() 函数不适用于 TailwindCSS 主题变量
- vba - 生成访问令牌导致未授权客户端
- reactjs - 反应表单输入值
- sql - 从 Instagram 用户名 sql 更新 InstagramID
- charts - PowerBI 是具有相同日期的自动求和值