Java 8 - 一旦 Stream 被消耗和操作就会出错,但在另一种情况下则不会

问题描述 投票:0回答:5

我是 Java 8 的新手,希望了解这两种场景之间的区别。我知道一旦一个流被操作和消耗,那么流就不能再次被重用,它会给出一个错误。

场景1:

List<String> title = Arrays.asList("Java8", "In", "Action");
        Stream<String> s = title.stream();
        s.forEach(System.out::println);
        s.forEach(System.out::println); // THIS WILL GIVE ERROR - streams has been already operated and closed.

当我运行此程序时,出现以下错误...这是公平的。

Java8
In
Action
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
    at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)
    at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
    at com.test.Java8InAction.CH4.TraversableOnlyOnce.main(TraversableOnlyOnce.java:12)

场景2:

// Filtering unique elements
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);

这里我也操作了流并关闭了终端操作,那为什么没有出现任何错误呢?

java java-8 java-stream
5个回答
10
投票

s.forEach
的两次调用使用相同的流,因此第一个示例中出现异常,而对
stream()
方法的调用 -->
numbers.stream()
每次都会生成(产生)一个新流,因此不会抛出 “java.lang.IllegalStateException:流已被操作或关闭”


5
投票

.stream()
创建了
Stream
的新实例,尽管事实上它是在同一个集合上调用的


1
投票

因为一个流只能被消费一次。如果您想多次使用,请使用供应商

Supplier<Stream<String>> streamSupplier = ()-> Stream.of("Java8", "In", "Action");

然后使用

get
创建一个新流。

streamSupplier.get().forEach(System.out::println);

但在第二种情况下,您每次都会创建一个新流。


0
投票

forEach
是终端操作。

执行终端操作后,流管道被认为已消耗,不能再使用;

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html


0
投票

所有中间操作都会返回一个新的实例Stream。 在任何单个 Stream 实例上,只能调用一个终端运算符,它会终止 Stream,使其无法使用。

中间操作:filter()、map()、flatMap()、distinct()、sorted()、peek()、limit()、skip() 终端操作:anyMatch()、allMatch()、noneMatch()、collect()、count()、findAny()、findFirst()、forEach()、min()、max()、reduce()、toArray ()

© www.soinside.com 2019 - 2024. All rights reserved.