Java 合并两条流

Java 合并两条流,java,merge,java-8,java-stream,Java,Merge,Java 8,Java Stream,我正在尝试实现一种方法,基于值的比较器将值合并到两个流中 我有办法做到这一点,我迭代流并将值插入Stream.Builder,但我还没有弄清楚如何生成一个延迟计算版本(许多流操作的方式),因此它也可以处理无限流 我只希望它对输入数据执行一次合并过程,而不是对流进行排序(事实上,流很可能是无序的;这种无序需要保留) 但我需要用惰性评估和流来实现这一点 为了解决这些意见,以下是一些示例输入和结果: 例1: merge( Stream.of(1, 2, 3, 1, 2, 3), Str

我正在尝试实现一种方法,基于值的
比较器将值合并到两个
流中

我有办法做到这一点,我迭代流并将值插入
Stream.Builder
,但我还没有弄清楚如何生成一个延迟计算版本(许多流操作的方式),因此它也可以处理无限流

我只希望它对输入数据执行一次合并过程,而不是对流进行排序(事实上,流很可能是无序的;这种无序需要保留)

但我需要用惰性评估和流来实现这一点

为了解决这些意见,以下是一些示例输入和结果:

例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
1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, -1 ...
例2:

merge(
    Stream.iterate(5, i->i-1),
    Stream.iterate(1, i->i+1),
    Comparator.naturalOrder()
);
将返回一个无限(嗯,一个
INT_MAX+5
item)流,该流将生成以下序列:

1, 2, 2, 2, 3, 3, 1, 2, 2, 2, 2, 3
1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, -1 ...

如您所见,这不仅仅是
concat(first,second).sort()
,因为(a)您无法对无限流进行排序,并且(b)即使您可以对流进行排序,它也不会给出所需的结果。

您需要实现
拆分器,而不是通过
Stream.Builder
。对于这一点,您甚至可以通过一个
迭代器
,因为它是一个相当连续的操作。轻轻地用番石榴

return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
    Iterators.mergeSorted(
      Arrays.asList(stream1.iterator(), stream2.iterator()),
      comparator),
    Spliterator.ORDERED),
  false /* not parallel */ );
来自番石榴的Iterables.mergestored()

public static <T> Iterable<T> mergeSorted(Iterable<? extends Iterable<? extends T>> iterables,
                Comparator<? super T> comparator)

publicstaticiterable合并排序(Iterabley您无法真正合并它们,因为除非您的问题没有说明所有内容,否则原始流都不会被排序;这意味着您无法提前知道要从流1中读取的元素是否应该在同一流中的另一个元素之前被有效地馈送,并且您与流2有相同的问题。您真的期待吗除了吞下它们和排序之外,还有一个解决方案?除了
Stream.concat(第一,第二)。sorted(c)
我不确定你能做多少…我真的不明白这应该做什么。@AJMansfield,你能给出一个你期望的输入和输出的例子吗?根据你的意思,这可能不是毫无希望,但我说不出来。你说的“合并”是什么意思流?如果它是排序导入的mergesort合并,那么它是可行的。@LouisWasserman在我看来,他好像是成对比较元素,即结果的前两个元素是每个流的第一个元素(以一种或另一种顺序),接下来的两个元素是每个流的第二个元素(以一种或另一种方式),等等。第一个例子就是这样。第二个例子破坏了我的猜测。没关系。我肯定遗漏了一些东西,但我不知道这是如何解决OP的问题的。根据OP的最新解释,这实际上是一个正确的答案。它不应该是
拆分器。有序的
?解决方案看起来不错,尽管问题非常复杂奇怪。你也可以使用源流拆分器,如果它们的大小都已知,你可以通过
spliterators.spliterator
求和并创建。这样,生成的拆分器可以更好地拆分,像
toArray()
这样的操作将更有效。