流中间操作 -> 非法状态异常

4

我一直认为Java8 Stream的中间操作在流上执行终端操作之前根本不会执行任何操作。

那么为什么这段代码会抛出IllegalStateException异常呢?

Stream<Integer> s = Stream.of(1, 2, 3);
s.limit(1);
s.limit(1);

"中间操作根本不做任何事情"这不是真的。它们创建一个新的流,并将其链接到该流。由于没有两个流可以依赖于同一源流,因此您无法调用多个操作。 "直到终端操作对流进行操作"。不是流 - 而是管道中的另一个流。 - a better oliver
1个回答

4
您遇到了关于Stream的一个普遍误解。由于其流畅的API,许多开发人员的第一个直觉是应用于流的每个方法都只返回它(类似于例如StringBuilder的行为 - myStringBuilder.append("Stack").append(" Overflow").append(" is").append(" is awesome!")。
然而,这不是真的。各种操作确实会返回一个流,但不是同一个对象,并且您收到的错误表明您尝试在同一个对象上应用两个操作,这是非法的。如果您使用纯粹流畅的形式,这将按预期工作。
Stream<Integer> s = Stream.of(1, 2, 3);
Integer i = s.limit(1).limit(1).findFirst().orElse(null); // returns 1;

正确,但这并不是我的重点。IllegalStateException 表示 Stream 已关闭或已对其进行操作。但为什么呢?我只使用了中间操作。 - Klaus Schulz
3
一个中间操作仍然在流上进行操作。一旦你执行了一个,就不能再执行另一个。 - Mureinik
中间操作如何在流上操作? s.peek(System.out::println).limit(1) 不会打印任何内容。 - Klaus Schulz
1
s.peek(System.out::println).limit(1) 将会执行, 但是不包括 s.limit(1); s.peek(System.out::println); - kuhajeyan
@kuhajeyan:不,s.peek(System.out::println).limit(1)不会。试一下吧。 - Klaus Schulz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接