关于java8里边Collectors.toMap()的空限制

在使用stream操作把list转为map的时候报了一个NPE,但是实际上HashMap是支持key或者value为null的,很是疑惑,查了一下发现是java8设计时候的一个限制。

java 复制代码
Map<Long, Long> exportStoreSupervisorIdMap = exportStoreList.stream().collect(Collectors.toMap(PhysicalStorePO::getId, PhysicalStorePO::getSupervisorId, (K1, K2) -> K1));

有一个对象的supervisorId是null,结果npe了。

这是因为在使用 Collectors.toMap() 时,如果值为 null,会抛出 NullPointerException。这是 Java 8 的一个限制。

有几种解决方案:

1.使用 Collectors.toMap 的另一个重载方法,显式指定 HashMap::new

java 复制代码
Map<Long, Long> exportStoreSupervisorIdMap = exportStoreList.stream()
    .collect(Collectors.toMap(
        PhysicalStorePO::getId,
        PhysicalStorePO::getSupervisorId,
        (k1, k2) -> k1,
        HashMap::new
    ));

2.先过滤掉 null 值

java 复制代码
Map<Long, Long> exportStoreSupervisorIdMap = exportStoreList.stream()
    .filter(store -> store.getSupervisorId() != null)
    .collect(Collectors.toMap(
        PhysicalStorePO::getId,
        PhysicalStorePO::getSupervisorId,
        (k1, k2) -> k1
    ));

3.使用普通的 for 循环

java 复制代码
Map<Long, Long> exportStoreSupervisorIdMap = new HashMap<>();
for (PhysicalStorePO store : exportStoreList) {
    exportStoreSupervisorIdMap.put(store.getId(), store.getSupervisorId());
}

4.使用自定义的收集器方法

java 复制代码
Map<Long, Long> exportStoreSupervisorIdMap = exportStoreList.stream()
    .collect(HashMap::new,
        (map, store) -> map.put(store.getId(), store.getSupervisorId()),
        HashMap::putAll);

推荐使用第 1 或第 2 种方案,取决于你是否需要保留 null 值:

如果需要保留 null 值,使用方案 1

如果不需要 null 值,使用方案 2

这个问题的根本原因是 Collectors.toMap 的实现不支持 null 值,这是一个设计决定。如果你确实需要包含 null 值,最好明确指定使用 HashMap 作为实现。

相关推荐
岁岁种桃花儿8 分钟前
CentOS7 彻底卸载所有JDK/JRE + 重新安装JDK8(实操完整版,解决kafka/jps报错)
java·开发语言·kafka
roman_日积跬步-终至千里44 分钟前
【Java并发】Java 线程池实战:警惕使用CompletableFuture.supplyAsync
java·开发语言·网络
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于Springboot的扶贫众筹平台为例,包含答辩的问题和答案
java·spring boot·后端
CodeSheep程序羊1 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
我是咸鱼不闲呀1 小时前
力扣Hot100系列19(Java)——[动态规划]总结(上)(爬楼梯,杨辉三角,打家劫舍,完全平方数,零钱兑换)
java·leetcode·动态规划
加油,小猿猿2 小时前
Java开发日志-双数据库事务问题
java·开发语言·数据库
yuluo_YX2 小时前
Reactive 编程 - Java Reactor
java·python·apache
山岚的运维笔记2 小时前
SQL Server笔记 -- 第20章:TRY/CATCH
java·数据库·笔记·sql·microsoft·sqlserver
南极企鹅3 小时前
springBoot项目有几个端口
java·spring boot·后端
清风拂山岗 明月照大江3 小时前
Redis笔记汇总
java·redis·缓存