用于输入数据的Java 8 Stream实用程序 [英] Java 8 Stream utilities for input data
问题描述
想象一下,通过回调或 InputStream
获得某种传入数据,您需要持续转换为Java 8 流
。我们不知道传入的数据流何时停止,但我们知道它可以停止。
Imagine having some sort of incoming data either by callback or an InputStream
that you need to continuously convert into a Java 8 Stream
. We don't know when the incoming data-stream stops, but we know that it can stop.
到目前为止我见过两个解决这个问题的方法,我对如何实现这一目标的最佳实践感兴趣。主要是因为我必须是某人以前面对的事情。必须有比下面的想法更简单的方法。
So far I've seen two ways of getting around this problem and I'm interested in the best practices on how to achieve this. Mainly because I this must be something someone has faced before. There must be a simpler way of doing it than the ideas below.
1)最简单的方法是将源视为供应商
并且只需使用 Stream.generate
来提供数据:
1) The most simple way is to treat the source as a Supplier
and just use Stream.generate
to serve data:
Stream.generate(() -> blockCallToGetData());
然而,这有一个缺点,即流永远不会结束。因此,只要输入源停止发送,流就会一直调用该方法。除非我们自然地抛出运行时异常,但这可能会很快变得难看。
However, this has the disadvantage, that the stream never ends. So whenever an input source stops sending, the stream just keeps calling the method. Unless we throw a Runtime exception naturally, but this can get ugly fast.
2)第二个想法是使用 Iterator
(转换为 Spliterator
),其中 next
方法阻塞,直到我们找到下一个元素。作为一个粗略的例子:
2) The second idea is to use a Iterator
(converted to a Spliterator
) where the next
method blocks until we find the next element. As a crude example:
class BlockingIterator implements Iterator<Data> {
@Override void boolean hasNext() {
return true;
}
@Override Data next() {
return blockCallToGetData();
}
}
这样做的好处是我可以通过在 hasNext
方法中返回 false
来停止流。但是,在我们不控制传入数据速度的情况下(例如在回调中),我们需要为迭代器保留一个就绪元素的缓冲区。在有人在迭代器上调用 next
之前,这个缓冲区可能会变得无限大。
The advantage of this is that I can stop the stream by returning false
in the hasNext
method. However, in situations where we do not control the speed of the incoming data (such as in a callback), we would need to keep a buffer of ready elements for the iterator. This buffer could grow infinitely big, before someone calls next
on the iterator.
所以,我的问题是;将阻塞输入提供给流的最佳做法是什么?
So, my question goes; what is the best practice for serving blocking input into a stream?
推荐答案
这个问题包含一个可疑的假设:那里有 是将阻塞输入提供给流的一种很好的做法。流不是反应性框架;虽然你可以把它变成一个有着大撬棍的人,但问题可能会在其他地方突然出现。 (EG考虑了这些用例,并得出结论认为我们最好提供能够在一个问题上完成工作而不是在两个工作中完成一半工作的东西。)
The question contains a questionable assumption: that there is a good practice for serving blocking input into a stream. Stream is not a reactive framework; while you can wedge it into being one with a big crowbar, the problems will likely pop out elsewhere as a result. (The EG considered these use cases and concluded that we were better off providing something that does a complete job at one problem rather than a half job at two.)
如果你需要一个反应框架,最好的做法是使用一个。 RxJava很棒。
If you need a reactive framework, the best practice is to use one. RxJava is great.
这篇关于用于输入数据的Java 8 Stream实用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!