从多个供应商生成一个流

时间:2014-08-14 15:11:05

标签: java java-8 java-stream

我正在尝试使用Java 8 Lambda / Stream API为简单的生产者/消费者系统建模,就像:

    Stream<Sample> samplesFlow = Stream.generate(new SampleSupplier());
    samplesFlow.forEach(new SampleConsumer());

我意识到对几个消费者的“规模”非常简单:

    samplesFlow
        .peek(new SampleConsumer1())
        .peek(new SampleConsumer2())
        .forEach(new SampleConsumer3());

但是如何在系统中添加新的生产者呢?是否有一些惯用或“优雅”的方式来从几个无限的供应商生成一个流?喜欢:

Stream.generate(new SampleSupplier1(),new SampleSupplier2());  // made it up

每个供应商都模拟网络侦听器从远程源获取数据。

提前致谢!

2 个答案:

答案 0 :(得分:4)

您没有指定如何组合提供的值。

如果您希望交替使用值,则解决方案是:

Stream.generate(supplier1).flatMap(x->Stream.of(x, supplier2.get()))

如果您想要某种配对,可以使用

Stream.generate(()->new Pair<>(supplier1.get(), supplier2.get()))

虽然由你来编写Pair类,因为jdk不提供这样的类。 (你可以滥用AbstractMap.SimpleEntry,但那是相当讨厌的。)


如果您有一个有限的Stream,您可以使用Stream.concat创建一个流,该流将在第二个流的项目之前处理第一个流的所有项目,但是,使用{{1默认情况下是无限的,所以你必须在第一个流上使用limit才能将它连接到另一个流,所以它不是一般的解决方案。


如果您只想查询每个Supplier一次,可以使用

Supplier

当然,如果你不需要对Stream.of(supplier1, supplier2).map(Supplier::get) 进行惰性评估,那么

Supplier

也会这样做。

答案 1 :(得分:0)

为了完整起见,另一个隐藏实施复杂性的选择是使用

StreamSupport.stream(Spliterator<T> spliterator, boolean parallel)

生成流并将Spliterator委托给遍历不同来源的元素。

在实施forEachRemaining(Consumer<? super T> action)

时,请注意一些注意事项