【发布时间】:2019-07-08 01:58:48
【问题描述】:
如何检查流实例是否已被使用(意味着调用了终端操作,这样对终端操作的任何进一步调用都可能因IllegalStateException: stream has already been operated upon or closed. 而失败?
理想情况下,我想要一个在流尚未被消费时不消费流的方法,如果流已被消费而没有从流方法中捕获IllegalStateException,则返回布尔值 false(因为使用异常进行控制flow 成本高且容易出错,尤其是在使用标准异常时)。
在异常抛出和布尔返回行为中类似于迭代器中的hasNext() 的方法(尽管没有与next() 的约定)。
例子:
public void consume(java.util.function.Consumer<Stream<?>> consumer, Stream<?> stream) {
consumer.accept(stream);
// defensive programming, check state
if (...) {
throw new IllegalStateException("consumer must call terminal operation on stream");
}
}
如果客户端代码调用此方法而不使用流,目标是尽早失败。
似乎没有办法做到这一点,我必须添加一个 try-catch 块来调用任何终端操作,如 iterator(),捕获一个异常并抛出一个新异常。
可接受的答案也可以是“不存在解决方案”,并有充分的理由说明为什么规范不能添加这种方法(如果存在充分的理由)。似乎 JDK 流通常在其终端方法的开头有这个 sn-ps:
// in AbstractPipeline.java
if (linkedOrConsumed)
throw new IllegalStateException(MSG_STREAM_LINKED);
所以对于那些流来说,实现这样的方法似乎并不难。
【问题讨论】:
-
好像没办法,按照here的讨论,连IllegalStateException都不能保证抛出。我想知道
iterator.hasNext()会做什么。 -
不要传递流,传递流提供者。这类似于传递迭代器而不是可迭代并尝试迭代两次。
-
您能否详细说明什么是消费者、“流已被消费”的确切含义以及您希望总体实现的目标。从你已经写的内容来看,这似乎不是很清楚。
-
@tkruse 你能举一个例子来解释你所说的“但是他们提供或消费的流实际上并没有被使用”吗?对于可能推断的内容,您似乎正在使用
Consumer而不是直接使用Stream,并且一旦您调用accept方法,您要确保它是否实际使用了提供的流。是这样吗?为什么(何时)这样的Consumer中的代码不会真正消耗流? -
为什么不知道流有没有被消费?流被消费后有什么用?为什么要保留对已使用的流的引用?我还想不出这个问题的用例。
标签: java java-stream