首页 归档 关于 learn love 工具

peek和map的异同之处

  • 两个函数都是中间操作,都非常的‘懒’,没有对Stream的终止操作,两个函数都不会工作。
  • peek函数的存在仅仅是为了debug,而map是Stream的一个核心函数,两个函数的地位不同。
  • 两个函数的参数(peek是Consumer,map是Function)起作用的时机不同。map的Function在生成新的Stream之前被执行,新Stream中的元素是上游Stream中元素经Function作用后的值。peek函数的Consumer工作在生成Stream之后。

一个有代表性的样例

以下面一段函数(来自peek函数的官方注释)为例解释peek和map两个函数工作机制的不同:

List<String> list = Stream.of("one", "two", "three", "four")
        .filter(e -> e.length() > 3)
        .peek(e -> System.out.println("Filtered value: " + e))
        .map(String::toUpperCase)
        .peek(e -> System.out.println("Mapped value: " + e))
        .collect(Collectors.toList());
System.out.println(list);

输出如下:

Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
[THREE, FOUR]

工作示意图如下:

工作流程概述:

  1. 初始Stream包含四个字符串:one,two,three和four
  2. Stream遇到的第一个中间操作是filter,filter的谓词是只保留长度大于3的字符串,经过谓词过滤后filter返回是一个仅包含两个字符串three和four的Stream1,谓词工作在Stream1生成之前。
  3. Stream遇到的第二个中间操作是peek,peek的Consumer是打印Stream中的字符串,peek直接生成一个和上游Stream1包含相同元素的Stream2,peek函数的Consumer工作在生成Stream2之后。
  4. Stream遇到的第三个中间操作是map,map的Function将字符串转换为全大写,Function作用于上游Stream2的每一个元素,并生成新的Stream3。
  5. Stream遇到的第四个中间操作是peek,peek的Consumer依然只是打印Stream4中的字符串,Consumer依然工作在Stream4生成之后。

map函数对Stream中元素执行的是映射操作,会以新的元素(map的结果)填充新的Stream,严格的讲map不是修改原来的元素。peek只能消费Stream中的元素,是否可以更该Stream中的元素,取决于Stream中的元素是否是不可变对象。如果是不可变对象,则不可修改Stream中的元素;如果是可变对象,则可以修改对象的值,但是无法修改对象的引用。

来源:

作者:大哥你先走
链接:https://www.jianshu.com/p/4fabc8a7abca