专栏名称: Java基基
一个苦练基本功的 Java 公众号,所以取名 Java 基基
目录
相关文章推荐
南城发布  ·  名单公布!抚州3所学校撤销! ·  4 小时前  
辽宁省教育厅  ·  培训送进岛!两百名教师集体“充电” ·  昨天  
辽宁省教育厅  ·  培训送进岛!两百名教师集体“充电” ·  昨天  
融媒吴江  ·  事关入学!吴江明天起开始申请! ·  昨天  
小哈聊事  ·  今年将推动大连海洋大学附属学校挂牌! ·  2 天前  
51好读  ›  专栏  ›  Java基基

Stream很好,Map很酷,但答应我别用toMap()!

Java基基  · 公众号  ·  · 2024-08-05 18:04

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本

来源:juejin.cn/post/
7383643463534018579


在 JDK 8 中 Java 引入了让人欲罢不能的 stream 流处理,可以说已经成为了我日常开发中不可或缺的一部分。

当完成一次流处理之后需要返回一个集成对象时,已经肌肉记忆的敲下 collect(Collectors.toList()) 或者 collect(Collectors.toSet()) 。你可能会想, toList toSet 都这么便捷顺手了,当又怎么能少得了 toMap() 呢。

答应我,一定打消你的这个想法,否则这将成为你噩梦的开端。

什么?你不信,没有什么比代码让人更痛彻心扉,让我们直接上代码。

让我们先准备一个用户实体类。

@Data
@AllArgsConstructor  
public class User {  
  
    private int id;  
    
    private String name;  
}

假设有这么一个场景,你从数据库读取 User 集合,你需要将其转为 Map 结构数据, key value 分别为 user id name

很快,你啪的一下就写出了下面的代码:

public class UserTest {
    @Test
    public void demo() {  
        List userList = new ArrayList<>();
        // 模拟数据
        userList.add(new User(1"Alex"));  
        userList.add(new User(1"Beth"));

        Map map = userList.stream()  
                .collect(Collectors.toMap(User::getId, User::getName));  
        System.out.println(map);  
    }
}

运行程序,你已经想好了开始怎么摸鱼,结果啪的一下 IllegalStateException 报错就拍你脸上,你定睛一看怎么提示 Key 值重复。

作为优秀的八股文选手,你清楚的记得 HashMap 对象 Key 重复是进行替换。你不信邪,断点一打,堆栈一看,硕大的 uniqKeys 摆在了面前,凭借四级 424 分的优秀战绩你顿时菊花一紧,点开一看,谁家好人 map key 还要去重判断啊。

好好好,这么玩是吧,你转身打开浏览器一搜,原来需要自己手动处理重复场景,啪的一下你又重新改了一下代码:

public class UserTest {
    @Test
    public void demo() {  
        List userList = new ArrayList<>();
        // 模拟数据
        userList.add(new User(1"Alex"));  
        userList.add(new User(2null));
        
        Map map = userList.stream()  
                .collect(Collectors.toMap(User::getId, User::getName, (oldData, newData) -> newData));  
        System.out.println(map);  
    }
}

再次执行程序,你似乎已经看到知乎的摸鱼贴在向你招手了,结果啪的一下 NPE 又拍在你那笑容渐渐消失的脸上。

静下心来,本着什么大风大浪我没见过的心态,断点堆栈一气呵成,而下一秒你又望着代码陷入了沉思,我是谁?我在干什么?

鼓起勇气,你还不信今天就过不去这个坎了,大手一挥,又一段优雅的代码孕育而生。

public class UserTest {
    @Test
    public void demo() {  
        List userList = new ArrayList<>();
        // 模拟数据
        userList.add(new User(1"Alex"));  
        userList.add(new User(1"Beth"));
        userList.add(new User(2null));
        
        Map map = userList.stream()  
                .collect(Collectors.toMap(  
                    User::getId,  
                    it -> Optional.ofNullable(it.getName()).orElse(""),  
                    (oldData, newData) -> newData)  
                );
        System.out.println(map);  
    }
}

优雅,真是太优雅了,又是 Stream 又是 Optional ,可谓是狠狠拿捏技术博文的 G 点了。

这时候你回头一看,我需要是什么来着?这 TM 不是一个循环就万事大吉了吗,不信邪的你回归初心,回归了 for 循环的怀抱,又写了一版。







请到「今天看啥」查看全文