Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于输入数据的Java8流实用程序_Java_Parsing_Java 8_Java Stream - Fatal编程技术网

用于输入数据的Java8流实用程序

用于输入数据的Java8流实用程序,java,parsing,java-8,java-stream,Java,Parsing,Java 8,Java Stream,想象一下,通过回调或InputStream获得某种类型的传入数据,您需要不断地将其转换为Java8流。我们不知道传入的数据流何时停止,但我们知道它可以停止 到目前为止,我已经看到了两种解决这个问题的方法,我对如何实现这一点的最佳实践很感兴趣。主要是因为我觉得这肯定是有人以前遇到过的。必须有一种比下面的想法更简单的方法 1) 最简单的方法是将源代码视为供应商,只需使用流即可。生成以提供数据: Stream.generate(() -> blockCallToGetData()); 然而,这

想象一下,通过回调或
InputStream
获得某种类型的传入数据,您需要不断地将其转换为Java8
流。我们不知道传入的数据流何时停止,但我们知道它可以停止

到目前为止,我已经看到了两种解决这个问题的方法,我对如何实现这一点的最佳实践很感兴趣。主要是因为我觉得这肯定是有人以前遇到过的。必须有一种比下面的想法更简单的方法

1) 最简单的方法是将源代码视为
供应商
,只需使用
流即可。生成
以提供数据:

Stream.generate(() -> blockCallToGetData());
然而,这有一个缺点,即流永远不会结束。因此,每当输入源停止发送时,流就会继续调用该方法。除非我们自然地抛出一个运行时异常,但这很快就会变得很糟糕

2) 第二个想法是使用
迭代器
(转换为
拆分器
),其中
下一个
方法阻塞,直到我们找到下一个元素。举个粗略的例子:

class BlockingIterator implements Iterator<Data> {

  @Override void boolean hasNext() {
    return true;
  }

  @Override Data next() {
    return blockCallToGetData();
  }

}
类BlockingIterator实现迭代器{
@重写void boolean hasNext(){
返回true;
}
@覆盖数据下一步(){
返回blockCallToGetData();
}
}
这样做的好处是,我可以通过在
hasNext
方法中返回
false
来停止流。然而,在我们无法控制传入数据的速度的情况下(例如在回调中),我们需要为迭代器保留一个就绪元素的缓冲区。在有人在迭代器上调用
next
之前,这个缓冲区可能会无限大


所以,我的问题是;向流中提供阻塞输入的最佳实践是什么?

这个问题包含一个可疑的假设:有一个向流中提供阻塞输入的良好实践。流不是一个反应框架;虽然你可以用一个大撬棍把它撬开,但问题很可能会在其他地方出现。(EG考虑了这些用例,并得出结论,我们最好在一个问题上提供一个完整的解决方案,而不是在两个问题上提供一半的解决方案。)


如果您需要一个反应式框架,最佳实践是使用一个。RxJava很棒

这个问题包含一个有问题的假设:有一个很好的实践可以为流提供阻塞输入。流不是一个反应框架;虽然你可以用一个大撬棍把它撬开,但问题很可能会在其他地方出现。(EG考虑了这些用例,并得出结论,我们最好在一个问题上提供一个完整的解决方案,而不是在两个问题上提供一半的解决方案。)

如果您需要一个反应式框架,最佳实践是使用一个。RxJava很棒

在中,我们通过使用JDK流可以读取的(simple react)(JDK队列数据结构上的异步包装器)解决了这个问题。如果队列关闭,流将自动断开连接

快速生产者/慢速消费者问题可以通过队列解决。如果(simple react)异步队列由一个有界阻塞队列支持,那么一旦队列满了,它将自动减慢(阻塞)任何正在生成的线程

相比之下,LazyFutureStream流实现在内部使用非阻塞队列,如果没有数据存在,甚至会尝试将自己从队列中的数据使用者转变为生产者(因此它可以作为完全非阻塞流运行)

示例使用:

PushableLazyFutureStream pushable=new PushableStreamBuilder()
.背压超过(100)
.带背压(真实)
.pushableLazyFutureStream();
//pushable.getInput().fromStream(输入);也可以添加输入数据
pushable.getInput().add(100);
pushable.getInput().close();
List List=pushable.getStream().collect(Collectors.toList());
//名单为[100]
在中,我们通过使用JDK流可以读取的(simple react)(JDK队列数据结构上的异步包装器)解决了这个问题。如果队列关闭,流将自动断开连接

快速生产者/慢速消费者问题可以通过队列解决。如果(simple react)异步队列由一个有界阻塞队列支持,那么一旦队列满了,它将自动减慢(阻塞)任何正在生成的线程

相比之下,LazyFutureStream流实现在内部使用非阻塞队列,如果没有数据存在,甚至会尝试将自己从队列中的数据使用者转变为生产者(因此它可以作为完全非阻塞流运行)

示例使用:

PushableLazyFutureStream pushable=new PushableStreamBuilder()
.背压超过(100)
.带背压(真实)
.pushableLazyFutureStream();
//pushable.getInput().fromStream(输入);也可以添加输入数据
pushable.getInput().add(100);
pushable.getInput().close();
List List=pushable.getStream().collect(Collectors.toList());
//名单为[100]

我认为您为迭代器描述的问题与基于供应商的方法相同。如果您无法控制传入数据的速度,并且当您不读取数据时,数据不会停止传入,那么您必须对其进行缓冲。请注意,我所知道的任何I/O源都不是这种情况。I/O源总是阻塞等待接收端确认接收。此外,如果您有一个异步数据源,那么最好使用异步API(如RxJava)来处理它。我认为您为迭代器描述的问题是基于供应商的方法所共有的。如果您无法控制传入数据的速度,并且当您不读取数据时,数据不会停止传入,那么您必须对其进行缓冲。注t
 PushableLazyFutureStream<Integer> pushable = new PushableStreamBuilder()
            .withBackPressureAfter(100)
            .withBackPressureOn(true)
            .pushableLazyFutureStream();

    // pushable.getInput().fromStream(input); would also be acceptable to add input data
    pushable.getInput().add(100); 
    pushable.getInput().close();

    List list = pushable.getStream().collect(Collectors.toList());

     //list is [100]