我正在学习Java 8 lambda表达式的过程,并且想问一下我遇到的函数接口中与peek
方法相关的以下Java代码。
在IDE上执行程序时,它不提供输出。我原以为它会给iconBase:"fontawesome",tickIcon:"fa fa-check"
。
2, 4, 6
答案 0 :(得分:60)
我假设你在Java 9下运行它?您没有更改流的SIZED
属性,因此根本不需要执行map
或peek
。
换句话说,您所关心的只是count
作为最终结果,但同时您不会以任何方式改变List
的初始大小(例如,通过filter
或distinct
)这是在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上,所以它必须是一个新的优化。