我正在尝试使用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
每个供应商都模拟网络侦听器从远程源获取数据。
提前致谢!
答案 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)