Java8流何时被认为是消费的?
我的理解是,一旦执行了诸如Java8流何时被认为是消费的?,java,java-8,java-stream,Java,Java 8,Java Stream,我的理解是,一旦执行了诸如forEach()或count()之类的终端操作,就会认为Java 8流被消费 然而,下面的测试用例multipleFilters\u-separate抛出一个IllegalStateException,即使filter是一个惰性的中间操作,只是被称为两个语句。然而,我可以将这两个过滤操作链接到一个语句中,并且它可以工作 @Test(expected=IllegalStateException.class) public void multipleFilters_sep
forEach()
或count()
之类的终端操作,就会认为Java 8流被消费
然而,下面的测试用例multipleFilters\u-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);
}
@Test(预期为IllegalStateException.class)
public void multipleFilters_separate(){
流积分=流积分(1.1,2.2,3.3);
内部过滤器(d->d>1.3);
ints.filter(d->d>2.3).forEach(System.out::println);
}
@试验
公共无效多重过滤器_管道(){
流积分=流积分(1.1,2.2,3.3);
内部过滤器(d->d>1.3)
.过滤器(d->d>2.3)
.forEach(System.out::println);
}
由此,我假设一个流
被认为是在使用它的第一个语句之后被消费的,不管该语句是否调用终端操作。听起来对吗?一旦执行了终端操作,就认为消耗了流。但是,正如流
javadoc中所述,对于同一流
实例,甚至不应该执行多个中间操作:
一个流只能操作一次(调用中间或终端流操作)。例如,这排除了“分叉”流,即同一个源向两个或多个管道提供数据,或对同一个流进行多次遍历如果流实现检测到流正在被重用,它可能会抛出IllegalStateException。但是,由于某些流操作可能返回其接收器而不是新的流对象,因此可能无法在所有情况下检测重用
对于中间流操作,您应该调用上一个操作返回的流上的下一个操作:
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);
}
public void multipleFilters_separate(){
流积分=流积分(1.1,2.2,3.3);
ints=ints.filter(d->d>1.3);
ints.filter(d->d>2.3).forEach(System.out::println);
}
根据以下内容:
流只能操作一次(调用中间或终端流操作)。例如,这排除了“分叉”流,即同一个源向两个或多个管道提供数据,或对同一个流进行多次遍历。如果流实现检测到流正在被重用,它可能会抛出IllegalStateException
。然而,由于某些流操作可能返回其接收器而不是新的流对象,因此可能无法在所有情况下检测重用
在您的例子中,对过滤器的调用本身检测到有人试图将您的流分成两个不同的流。添加终端操作后,它不是等待并导致问题,而是执行先发制人的攻击,以从任何堆栈跟踪中明确问题的确切位置。ints.filter(d->d>1.3)
什么都不做。我不认为OP想表达的是这一点,因为很明显,这两个filter
语句是多余的。不,我想评论一下你所说的“编写它的正确方法”。我感觉到分叉流是预期的用例,而不是您建议的链式流。@JoeC我不确定OP是否打算分叉流。我不是有意想到分叉流,只是为了可读性将我的操作拆分为单独的语句,并添加更详细的注释。但是,这样做似乎充满了危险。@craigcaulfield正如我所说,(如果你没有链接调用),你必须保留对每个流
操作返回的流的引用,并调用新流
上的下一个操作。