在使用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 作为实现。