Java 8与Java 9中的Stream.peek()方法

时间:2018-01-12 07:51:32

标签: java lambda java-8 java-9 peek

我正在学习Java 8 lambda表达式的过程,并且想问一下我遇到的函数接口中与peek方法相关的以下Java代码。

在IDE上执行程序时,它不提供输出。我原以为它会给iconBase:"fontawesome",tickIcon:"fa fa-check"

2, 4, 6

2 个答案:

答案 0 :(得分:60)

我假设你在Java 9下运行它?您没有更改流的SIZED属性,因此根本不需要执行mappeek

换句话说,您所关心的只是count作为最终结果,但同时您不会以任何方式改变List的初始大小(例如,通过filterdistinct)这是在Streams中完成的优化。

顺便说一句,即使您添加了一个虚拟过滤器,这也会显示您的期望:

values.stream ()
      .map(n -> n*2)
      .peek(System.out::print)
      .filter(x -> true)
      .count();

答案 1 :(得分:56)

以下是来自Stream界面的Javadoc的一些相关引用:

  

允许流实现在优化结果计算方面具有显着的自由度。例如,流实现可以自由地从流管道中删除操作(或整个阶段) - 因此可以省略对行为参数的调用 - 如果它可以证明它不会影响计算结果。这意味着行为参数的副作用可能并不总是被执行并且不应该被依赖,除非另有说明(例如通过forEach和forEachOrdered的终端操作)。 (有关此类优化的具体示例,请参阅count()操作中记录的API说明。有关更多详细信息,请参阅流包文档的副作用部分。)

更具体地说,来自count()方法的Javadoc:

  

API注意:

     

如果实现可以直接从流源计算计数,则实现可以选择不执行流管道(顺序或并行)。在这种情况下,不会遍历任何源元素,并且不会评估中间操作。除了诸如调试之类的无害情况之外,强烈不鼓励具有副作用的行为参数可能会受到影响。例如,请考虑以下流:

List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();
     

流源(List)所涵盖的元素数量是已知的,并且中间操作peek不会从流中注入或删除元素(flatMap或过滤器操作可能就是这种情况)。因此,count是List的大小,不需要执行管道,并且作为副作用,打印出列表元素。

这些引号只出现在Java 9的Javadoc上,所以它必须是一个新的优化。