我有一个用例,其中有一个数据源,让我们说:每秒钟,有一个新字符串从该数据源中发出。
我想创建一个管道,如果有新字符串到达,它将被推送通过该管道进行处理。
我想Java 8引入的Stream API可以做到这一点,因为它具有处理任意集合数据的便捷功能,但是我想将收集数据的部分跳过到一个单独的集合中,直接将到达的数据分配到我刚刚创建的Stream中。
有什么办法吗?
答案 0 :(得分:6)
要执行您描述的操作,您需要某种阻止。我会使用BlockingQueue
(任何方法都可以-如果您想避免收集,请使用SynchronousQueue
,它根本没有内部状态),并从中创建一个无限的Stream
使用Stream.generate
。
示例:
class StreamableQueue<T> {
private BlockingQueue<T> dataSource;
Stream<T> asStream() {
return Stream.generate(this::takeFromDataSource);
}
private T takeFromDataSource() {
try {
return dataSource.take();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
当然,作为BlockingQueue
提供给此类的dataSource
需要从另一个线程中馈入元素。
EDIT :较小的补充-您可以使用:
takeFromDataSource()
方法的@SneakyThrows
注释Sneaky.supplier
/ Unchecked.supplier
方法,可简化转换为:Stream.generate(Sneaky.supplier(dataSource::take))
答案 1 :(得分:0)
好的,因此这种特殊情况的答案有些不同。
虽然answer of Tomasz Linkowski似乎是一个非常好的解决方案,但主要的问题是我的函数比BlockingQueue
所建议的更具顺序性,这不利于可读性。
所以我想出了Stream.Builder
,实际上这正是我所需要的,仅此而已。