Collectors.toMap不允许Null Value导致NPE

背景

开发过程中的代码如下:

    public static void main(String[] args) {
        final ProductionDataVo productionDataVo = new ProductionDataVo().setDate("2023");
        List<ProductionDataVo> productionDataVoList = Collections.singletonList(productionDataVo);
        Map<String, Long> map = productionDataVoList.stream()
                .collect(toMap(ProductionDataVo::getDate, ProductionDataVo::getTotal, (v1, v2) -> v1));
        //
    }

    @Data
    @Accessors(chain = true)
    public static class ProductionDataVo{

        private String date;

        private Long total;
    }

其中ProductionDataVo::getTotal存在为null的情况,此时直接报错。

测试报错信息如下:

问题排查

综上所述,NPE只发生在list转map过程中,map的value值为null,但是openjdk的map是可以允许null的value的。查看报错,发现是java.util.HashMap.merge(HashMap.java:1225)抛出的异常,查看merge源码,如下:

可以看到,Collectors.toMap在底层使用的是Map::merge方法,而merge方法不允许null value,无论该Map实例是否支持null value

问题解决

找到原因了,那么如何解决呢?

1.如果不需要为null的数据,则直接过滤。

2.如果需要全部数据,则可以使用forEach将list转map