答应我别用toMap()!

点击上方"程序员蜗牛g",选择"设为星标"跟蜗牛哥一起,每天进步一点点程序员蜗牛g大厂程序员一枚 跟蜗牛一起 每天进步一点点31篇原创内容**公众号

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

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

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

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

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

less 复制代码
@Data
@AllArgsConstructor  
public class User {  
  
    private int id;  
    
    private String name;  
}

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

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

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

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

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

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

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

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

再次执行程序,结果啪的一下 NPE 又拍在你那笑容渐渐消失的脸上。

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

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

csharp 复制代码
public class UserTest {
    @Test
    public void demo() {  
        List<User> userList = new ArrayList<>();
        // 模拟数据
        userList.add(new User(1, "Alex"));  
        userList.add(new User(1, "Beth"));
        userList.add(new User(2, null));
        
        Map<Integer, String> 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 循环的怀抱,又写了一版。

csharp 复制代码
public class UserTest {
    @Test
    public void demo() {  
        List<User> userList = new ArrayList<>();
        // 模拟数据
        userList.add(new User(1, "Alex"));  
        userList.add(new User(1, "Beth"));
        userList.add(new User(2, null));

        Map<Integer, String> map = new HashMap<>();  
        userList.forEach(it -> {  
            map.put(it.getId(), it.getName());  
        });  
        System.out.println(map);
    }
}

看着运行完美无缺的代码,你一时陷入了沉思,数分钟过去了,你删除了 for 循环,换上 Stream 与 Optional 不羁的外衣,安心的提交了代码,这口细糠一定也要让好同事去尝一尝。

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

相关推荐
一 乐21 分钟前
酒店客房预订|基于springboot + vue酒店客房预订系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
计算机毕设指导622 分钟前
基于Spring Boot的防诈骗管理系统【源码文末联系】
java·spring boot·后端·spring·tomcat·maven·intellij-idea
开心就好202526 分钟前
IOScer 开发环境证书包括哪些,证书、描述文件与 App ID 的协同管理实践
后端
码事漫谈36 分钟前
终于找到我想要的远程工具了!
后端
我家领养了个白胖胖36 分钟前
MCP模型上下文协议 Model Context Protocol & 百度地图MCP开发
java·后端·ai编程
Coder_Boy_39 分钟前
基于DDD+Spring Boot 3.2+LangChain4j构建企业级智能客服系统
java·人工智能·spring boot·后端
开心猴爷40 分钟前
苹果商店 App 上架要求,探讨如何通过系统审核
后端
开心就好202540 分钟前
Flutter 应用加固在真实项目中的实践方式,当 Dart 之外还有一整个 IPA
后端
黄俊懿1 小时前
【深入理解SpringCloud微服务】Spring-Security作用与原理解析
java·后端·安全·spring·spring cloud·微服务·架构师
我是谁的程序员1 小时前
iOS 开发中证书创建与管理中的常见问题
后端