Java 8中如何避免Collectors#toMap因null值抛出空指针异常?
Java 8中如何避免Collectors#toMap因null值抛出空指针异常?
这个问题我之前踩过坑!Java 8里的Collectors.toMap()确实有个容易忽略的限制——当流中元素的value为null时,它会直接抛出NullPointerException。这是因为这个方法底层依赖HashMap.merge()实现,而merge()本身不允许value为null。给你几个实用的解决办法:
方法一:手动遍历填充Map(最简单直接)
既然HashMap本身是支持value为null的,那我们可以跳过Collectors.toMap(),直接手动遍历流元素填充Map:private static Map<String, Object> toParamMap(List<Map.Entry<String, Object>> params) { Map<String, Object> paramMap = new HashMap<>(); params.forEach(entry -> paramMap.put(entry.getKey(), entry.getValue())); return paramMap; }这个写法逻辑清晰,没有额外的复杂度,适合大多数场景。
方法二:自定义支持null值的Collector(复用性强)
如果你习惯用Stream的collect操作,可以自己写一个支持null value的Collector,以后遇到类似场景直接复用:// 自定义支持null值的toMap Collector private static <T, K, U> Collector<T, ?, Map<K, U>> toNullableMap( Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return Collector.of( HashMap::new, // 供应一个空的HashMap作为容器 (map, element) -> map.put(keyMapper.apply(element), valueMapper.apply(element)), // 累加器:直接put键值对 (map1, map2) -> { // 组合器:合并两个Map map1.putAll(map2); return map1; } ); } // 使用自定义Collector private static Map<String, Object> toParamMap(List<Map.Entry<String, Object>> params) { return params.stream().collect(toNullableMap(Map.Entry::getKey, Map.Entry::getValue)); }这个Collector完全仿照
Collectors.toMap()的逻辑,但用put和putAll替代了会报错的merge,完美支持null值。
最后补充下:原代码报错的核心原因是Collectors.toMap()的双参数版本,在处理元素时会调用Map.merge(key, value, throwingMerger()),而merge方法要求传入的value不能为null,否则就会抛出NPE。
备注:内容来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

