我使用peek
尝试了以下Java 8代码片段。
List<String> list = Arrays.asList("Bender", "Fry", "Leela");
list.stream().peek(System.out::println);
然而,控制台上没有打印出任何内容。如果我这样做:
list.stream().peek(System.out::println).forEach(System.out::println);
我看到以下内容同时输出了peek和foreach调用。
Bender
Bender
Fry
Fry
Leela
Leela
foreach
和peek
都接纳(Consumer<? super T> action)
那么为什么输出会有所不同呢?
答案 0 :(得分:38)
Javadoc提及以下内容:
作为中间操作的中间操作返回一个新流。他们总是懒惰;执行诸如filter()之类的中间操作实际上并不执行任何过滤,而是创建一个新流,当遍历时,该流包含与给定谓词匹配的初始流的元素。在执行管道的终端操作之前,不会开始遍历管道源。
peek
什么都不做。在应用foreach
等终端操作时,结果会打印出来。
答案 1 :(得分:6)
peek
的文档说
返回由此流的元素组成的流,另外还会在结果流中使用元素时对每个元素执行提供的操作。 这是一个中间操作。
因此,您必须对System.out.println
的结果流执行任何操作。
答案 2 :(得分:6)
来自Stream的文档,用于窥视方法:
...另外,在结果流中消耗元素时,对每个元素执行提供的操作。
答案 3 :(得分:0)
Java-8中的Strema是懒惰的,另外,如果一个接一个地在流中有两个链式操作,那么第一个操作在第一个完成处理一个数据元素单元时开始(假设有一个流中的终端操作)。
这就是为什么你可以看到重复的名字字符串得到输出。