AJM*_*eld 10 java merge java-8 java-stream
我试图实现一个方法来合并两个Stream
s中的值基于a Comparator
的值.
我有办法做到这一点,我迭代流并将值插入到一个Stream.Builder
,但我还没有弄清楚如何制作一个懒惰评估版本(许多流操作的方式),所以它可以处理无限流.
我想要它做的就是对输入数据执行单个合并传递,而不是对流进行排序(实际上,流很可能是无序的;需要保留这种混乱).
static Stream<E> merge(Stream<E> first, Stream<E> second, Comparator<E> c)
Run Code Online (Sandbox Code Playgroud)
我如何懒惰地合并这样的两个流?
如果我用两个Queue
s作为输入,一些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);
}
Run Code Online (Sandbox Code Playgroud)
但我需要使用惰性评估和流来完成这项工作.
为了解决这些评论,这里有一些示例输入和结果:
例1:
merge(
Stream.of(1, 2, 3, 1, 2, 3),
Stream.of(2, 2, 3, 2, 2, 2),
Comparator.naturalOrder()
);
Run Code Online (Sandbox Code Playgroud)
将返回一个将产生此序列的流:
1, 2, 2, 2, 3, 3, 1, 2, 2, 2, 2, 3
Run Code Online (Sandbox Code Playgroud)
例2:
merge(
Stream.iterate(5, i->i-1),
Stream.iterate(1, i->i+1),
Comparator.naturalOrder()
);
Run Code Online (Sandbox Code Playgroud)
会返回一个INT_MAX + 5
产生序列的无限(井,项)流:
1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, -1 ...
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这不仅仅是concat(first,second).sort()
因为(a)您无法对无限流进行排序,并且(b)即使您可以对流进行排序,也不能提供所需的结果.
你需要实现一个Spliterator
,而不是通过Stream.Builder
.为此,您甚至可能只是通过一个Iterator
,因为它是一个相当顺序的操作.轻轻地使用番石榴,
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
Iterators.mergeSorted(
Arrays.asList(stream1.iterator(), stream2.iterator()),
comparator),
Spliterator.ORDERED),
false /* not parallel */ );
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7665 次 |
最近记录: |