Java流:通过现有流放置新元素

Java流:通过现有流放置新元素,java,java-8,stream,java-stream,Java,Java 8,Stream,Java Stream,我有一个用例,其中我有一个数据源,比如说:每秒钟,一个新的字符串都来自该数据源 我想创建一个管道,如果一个新字符串到达,它将被推送到管道中进行处理 我想Java8引入的StreamAPI可以做到这一点,因为它有方便的函数来处理任意集合的数据,但是我想跳过将数据收集到单独集合的部分,并将到达的数据直接发送到我刚刚创建的流 有什么方法可以做到这一点吗?为了完成您描述的任务,您需要某种阻塞。我会使用a(任何类型都可以——如果您想要避免集合,请使用,它根本没有内部状态),并使用创建一个无限的流 例如:

我有一个用例,其中我有一个数据源,比如说:每秒钟,一个新的字符串都来自该数据源

我想创建一个管道,如果一个新字符串到达,它将被推送到管道中进行处理

我想Java8引入的StreamAPI可以做到这一点,因为它有方便的函数来处理任意集合的数据,但是我想跳过将数据收集到单独集合的部分,并将到达的数据直接发送到我刚刚创建的流


有什么方法可以做到这一点吗?

为了完成您描述的任务,您需要某种阻塞。我会使用a(任何类型都可以——如果您想要避免集合,请使用,它根本没有内部状态),并使用创建一个无限的

例如:

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);
        }
    }
}
class StreamableQueue{
私有阻塞队列数据源;
流助理(){
return Stream.generate(this::takeFromDataSource);
}
私有T takeFromDataSource(){
试一试{
返回dataSource.take();
}捕获(中断异常例外){
抛出新的运行时异常(ex);
}
}
}
当然,作为
dataSource
提供给此类的
BlockingQueue
需要从不同的线程提供元素


编辑:一个小的添加-您可以使用以下命令,而不是使用try-catch:

  • takeFromDataSource()
    方法上的注释
  • 或者,更好的是,它简化了转换为:
    Stream.generate(skelky.supplier(dataSource::take))

好的,所以这个特殊情况的答案有点不同

虽然看起来是一个非常好的解决方案,但它的主要问题是,我的函数比
BlockingQueue
s所建议的更顺序,这对可读性有害


因此,我提出了
Stream.Builder
,这正是我需要的,仅此而已。

Java8流不适用于此,请看一下反应式框架。这应该是可能的。如果你想尝试,实现并使用它来创建你的流。你可以用java流来实现,但这是一种黑客行为。问题是从你在问题中忽略的部分开始的。你打算怎么处理你的小溪?“将到达的数据直接发送到流”本身并不是目的。开始讨论实际目标,您将了解为什么流不是最佳选择。不,反应式编程不一定要“大”。像“每当新项目到达时,执行xyz”这样的任务是最简单的例子。请看……与其说数据源是连续的,不如说是有限的,因为使用
Stream.Builder
创建
流的唯一方法是知道它应该包含的所有数据。很明显,这是你在问题中错列的。但我很高兴你找到了解决问题的办法!:)如果我不够坦率,我很抱歉。由于streambuilder文档中使用了几乎完全相同的词,因此我想跳过将数据收集到单独收集部分的部分,以便于找到解决方案