cra*_*eld 18 java java-8 java-stream
我的理解是,Stream
一旦执行终端操作(例如forEach()
或)count()
,就认为Java 8 被消耗.
但是,multipleFilters_separate
下面的测试用例抛出一个IllegalStateException
即使filter
是一个懒惰的中间操作,只是作为两个语句调用.然而,我可以将两个过滤操作链接到一个语句中并且它可以工作.
@Test(expected=IllegalStateException.class)
public void multipleFilters_separate() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints.filter(d -> d > 1.3);
ints.filter(d -> d > 2.3).forEach(System.out::println);
}
@Test
public void multipleFilters_piped() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints.filter(d -> d > 1.3)
.filter(d -> d > 2.3)
.forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
从这开始,我假设Stream
在第一个使用它的语句之后被认为是消耗的,无论该语句是否调用终端操作.听起来不错吗?
Era*_*ran 20
Stream
一旦执行终端操作,就认为A 被消耗.但是,即使是多个中间操作也不应该针对同一个Stream
实例执行,如Stream
javadoc 中所述:
应该仅对一个流进行操作(调用中间或终端流操作).例如,这排除了"分叉"流,其中相同的源提供两个或更多个管道,或者同一个流的多个遍历.如果流实现检测到正在重用流,则它可能会抛出IllegalStateException.但是,由于某些流操作可能返回其接收器而不是新的流对象,因此可能无法在所有情况下检测重用.
在中间流操作的情况下,您应该调用上一个操作Stream
返回的下一个操作:
public void multipleFilters_separate() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints = ints.filter(d -> d > 1.3);
ints.filter(d -> d > 2.3).forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*e C 11
应该仅对一个流进行操作(调用中间或终端流操作).例如,这排除了"分叉"流,其中相同的源提供两个或更多个管道,或者同一个流的多个遍历.
IllegalStateException
如果检测到流正在被重用,则可能会抛出流实现.但是,由于某些流操作可能返回其接收器而不是新的流对象,因此可能无法在所有情况下检测重用.
在您的情况下,对filter
自身的调用是检测到将您的流分成两个不同的流的尝试.它不是在添加终端操作后等待并导致问题,而是执行先发制人的攻击,以便从任何堆栈跟踪中清楚地了解您的问题所在.