Java 8-一旦Stream被消耗并运行并给出错误,但在另一种情况下则不会

时间:2018-10-07 13:46:06

标签: java java-8 java-stream

我是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);

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

4 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

因为流只能被使用一次。如果您想使用多次,请使用Supplier

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

然后使用get创建新的流。

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

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

答案 3 :(得分:0)

forEach是终端操作。

  

执行终端操作后,流管道被视为已消耗,无法再使用;

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