Java Stream中peek和map不为人知的秘密

有段代码如下,这里我开始用Java Stream 中的map来修改对象的值

 

less

代码解读

复制代码

retPage.setRecords(retList.stream().map(questionPageVO -> { questionPageVO.setCreateUserName(userIdAndUserMap.get(questionPageVO.getCreateId()).getUsername()); questionPageVO.setUpdateUserName(userIdAndUserMap.get(questionPageVO.getUpdateId()).getUsername()); return questionPageVO; }).collect(Collectors.toList()));

但idea提示我这里可以替换为peek,

替换之后的写法

 

less

代码解读

复制代码

retPage.setRecords(retList.stream().peek(questionPageVO -> { questionPageVO.setCreateUserName(userIdAndUserMap.get(questionPageVO.getCreateId()).getUsername()); questionPageVO.setUpdateUserName(userIdAndUserMap.get(questionPageVO.getUpdateId()).getUsername()); }).collect(Collectors.toList()));

这样确实更简单整洁了,但peek这样用真的合适吗? 今天我们就来讲一下peek的一些不为人知的缺点。

peek的基本定义和使用

  1. 先来看看peek的定义:
 

swift

代码解读

复制代码

Stream<T> peek(Consumer<? super T> action);

peek方法接受一个Consumer参数,返回一个Stream结果。

Consumer是一个FunctionalInterface,它需要实现的方法是下面这个:

 

arduino

代码解读

复制代码

void accept(T t);

accept对传入的参数T进行处理,但是并不返回任何结果。

  1. peek的基本使用
 

csharp

代码解读

复制代码

public static void baseUse() { List<Integer> list = Stream.of(1,2,3) .peek(System.out::println) .collect(Collectors.toList()); System.out.println(list); }

输出内容:

 

csharp

代码解读

复制代码

1 2 3 [1, 2, 3]

3. peek的流式处理

 

csharp

代码解读

复制代码

public static void peekForEach() { Stream.of(1,2,3) .peek(System.out::println) .forEach(e -> System.out.println("forEach:" + e)); }

输出内容:

 

makefile

代码解读

复制代码

1 forEach:1 2 forEach:2 3 forEach:3

通过输出内容也可以看出,流式处理流程,是对应流中每一个元素,分别经历peekforEach操作(即一个元素执行完所有流程),而不是等peek完所有元素元素后再执行forEach

坑一:Stream的懒执行策略

之所以有流操作,是因为有时候处理的数据比较多,无法一次性加载到内存中。

为了优化stream的链式调用效率,stream还提供了一个懒加载策略。

什么是懒加载呢?

懒加载也叫intermediate operation, 在stream的方法中,大部分都是懒加载,另外部分则是terminal operation, 例如collectcount等,当有这种非懒加载的方法调用时,整个链式都会被执行,如开始的baseUse示例。

peekmap,都是懒加载方法,即intermediate operation

intermediate operation的特点是立即返回,如果最后没有以terminal operation结束,intermediate operation实际上是不会执行的。

贴个官方解释图

让我们来看这个示例:

 

csharp

代码解读

复制代码

public static void peekLazy() { Stream.of(1,2,3) .peek(e -> System.out.println("peek lazy: " + e)); }

执行之后,结果什么都没输出,表示peek中的逻辑没有被调用这里就是很大的一个坑,使用的时候要注意。

同理这里map也是一样。

 

csharp

代码解读

复制代码

public static void mapLazy() { Stream.of(1,2,3) .map(e -> { e = e+1; System.out.println("map lazy: " + e); return e; }); }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值