【发布时间】:2014-05-23 08:36:35
【问题描述】:
我正在尝试实现一种方法,以基于 Comparator 的值合并两个 Streams 中的值。
我有办法做到这一点,我遍历流并将值插入Stream.Builder,但我无法弄清楚如何制作延迟评估版本(许多流操作的方式are),因此它也可以处理无限流。
我想要它做的只是对输入数据执行 single 合并传递,不 对流进行排序(实际上,流很可能是无序;这种无序需要保留)。
static Stream<E> merge(Stream<E> first, Stream<E> second, Comparator<E> c)
我怎样才能像这样懒惰地合并两个流?
如果我用两个Queues 作为输入和一些Consumer 作为输出来做这件事,那将相当简单:
void merge(Queue<E> first, Queue<E> second, Consumer<E> out, Comparator<E> c){
while(!first.isEmpty() && !second.isEmpty()
if(c.compare(first.peek(), second.peek()) <= 0)
out.accept(first.remove());
else
out.accept(second.remove());
for(E e:first)
out.accept(e);
for(E e:second)
out.accept(e);
}
但我需要通过惰性评估和流来做到这一点。
为了解决 cmets,以下是一些示例输入和结果:
示例 1:
merge(
Stream.of(1, 2, 3, 1, 2, 3),
Stream.of(2, 2, 3, 2, 2, 2),
Comparator.naturalOrder()
);
会返回一个会产生这个序列的流:
1, 2, 2, 2, 3, 3, 1, 2, 2, 2, 2, 3
示例 2:
merge(
Stream.iterate(5, i->i-1),
Stream.iterate(1, i->i+1),
Comparator.naturalOrder()
);
将返回一个无限的(嗯,一个INT_MAX + 5 项目)流,它会产生序列:
1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, -1 ...
如您所见,这不仅仅是concat(first,second).sort(),因为 (a) 您无法对无限流进行排序,并且 (b) 即使您可以对流进行排序,它也不会给出所需的结果。
【问题讨论】:
-
你不能真正合并它们,因为除非你的问题没有说明一切,否则原始流都没有被排序;这意味着您无法提前知道要从流 1 读取的元素是否应该在来自同一流的另一个元素之前有效地被馈送,并且您对流 2 也有同样的问题。除了吞下它们之外,您是否真的期望存在解决方案和排序?
-
除了
Stream.concat(first, second).sorted(c);我不确定你能做多少...... -
我真的不明白这应该做什么。 @AJMansfield,您能否给出您期望的输入和输出示例?根据你的意思,这可能不是那么绝望,但我不能说。 “合并”流是什么意思?如果它是,例如,从排序导入合并排序,它是可行的。
-
@LouisWasserman 在我看来他是在成对比较元素,即结果的前两个元素是每个流的第一个元素(以一个或另一个顺序),接下来的两个元素是每个流的第二个元素(一种或另一种)等......好吧,第一个示例遵循该模式。第二个破坏了我的猜想。没关系。
标签: java merge java-8 java-stream