【发布时间】:2018-11-12 02:04:44
【问题描述】:
我认为我研究过的所有资源都以一种或另一种方式强调一个流只能被消费一次,并且消费是通过所谓的终端操作来完成的(这对我来说很清楚)。
出于好奇,我尝试了这个:
import java.util.stream.IntStream;
class App {
public static void main(String[] args) {
IntStream is = IntStream.of(1, 2, 3, 4);
is.map(i -> i + 1);
int sum = is.sum();
}
}
最终抛出运行时异常:
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
at java.util.stream.IntPipeline.reduce(IntPipeline.java:456)
at java.util.stream.IntPipeline.sum(IntPipeline.java:414)
at App.main(scratch.java:10)
这很常见,我遗漏了一些东西,但仍然想问:据我所知,map 是一个中间(和惰性)操作,它自己对 Stream 执行 nothing。只有当终端操作sum(即急切操作)被调用时,Stream才会消费并操作。
但是为什么我必须把它们锁起来呢?
有什么区别
is.map(i -> i + 1);
is.sum();
和
is.map(i -> i + 1).sum();
?
【问题讨论】:
-
一个流应该只被操作一次(调用一个中间或终端流操作)。例如,这排除了“分叉”流,其中相同的源提供两个或多个管道,或者同一流的多次遍历。如果流实现检测到流正在被重用,它可能会抛出 IllegalStateException。但是,由于某些流操作可能返回其接收者而不是新的流对象,因此可能无法在所有情况下检测重用。
-
所有流都由一个拆分器驱动,每个拆分器只对单个批量计算有用
标签: java java-8 java-stream