在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。

【强制】在使用 java.util.stream.Collectors 类的 toMap()方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。

个人代码实测

@Test
    public void toMapValueNullTest1() {
        List<TestClass> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new TestClass(String.valueOf(i), null));
        }
        list.add(new TestClass("test1", "测试"));
        list.add(new TestClass("test2", "测试2"));
        System.out.println(list);
        Map<String, String> collect;
        try {
            //错误演示 未处理value为null的情况
            //原理:Collectors.toMap底层是基于Map.merge方法来实现的,而merge中value是不能为null的,如果为null,就会抛出空指针异常
            collect = list.stream().collect(Collectors.toMap(TestClass::getId, TestClass::getName, (s, s2) -> s2));
            System.out.println(collect);
        } catch (NullPointerException e) {
            System.out.println("value为null空指针异常");
        }
        //解决方案1 用filter过滤value为null的
        collect = list.stream().filter(testClass -> testClass.getName() != null).collect(Collectors.toMap(TestClass::getId, TestClass::getName, (s, s2) -> s2));
        System.out.println(collect);

        //解决方案2 手动实现重载方法
        Map<Object, Object> collect2 = list.stream().collect(HashMap::new, (map, testClass) -> map.put(testClass.getId(), testClass.getName()), HashMap::putAll);
        System.out.println(collect2);

        //解决方案3 使用原来的for循环或者foreach循环
        Map<String, String> collect3 = new HashMap<>();
        list.forEach(testClass -> collect3.put(testClass.getId(), testClass.getName()));
        System.out.println(collect3);

        //解决方案4 使用Optional包装value
        Map<String, Optional<String>> collect4 = list.stream().collect(Collectors.toMap(TestClass::getId, testClass -> Optional.ofNullable(testClass.getName())));
        System.out.println(collect4);

        //解决方案5 判断如果是null,变为特定的值 (不太好)
        Map<String, String> collect5 = list.stream().collect(Collectors.toMap(TestClass::getId, testClass -> testClass.getName() == null ? "ERROR:null" : testClass.getName()));
        System.out.println(collect5);

    }

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
class TestClass {
private String id;
private String name;
}
 

结果

[Test1.TestClass(id=0, name=null), Test1.TestClass(id=1, name=null), Test1.TestClass(id=2, name=null), Test1.TestClass(id=3, name=null), Test1.TestClass(id=4, name=null), Test1.TestClass(id=5, name=null), Test1.TestClass(id=6, name=null), Test1.TestClass(id=7, name=null), Test1.TestClass(id=8, name=null), Test1.TestClass(id=9, name=null), Test1.TestClass(id=test1, name=测试), Test1.TestClass(id=test2, name=测试2)]
value为null空指针异常
{test2=测试2, test1=测试}
{0=null, 1=null, 2=null, test2=测试2, 3=null, 4=null, 5=null, 6=null, 7=null, 8=null, 9=null, test1=测试}
{0=null, 1=null, 2=null, test2=测试2, 3=null, 4=null, 5=null, 6=null, 7=null, 8=null, 9=null, test1=测试}
{0=Optional.empty, 1=Optional.empty, test2=Optional[测试2], 2=Optional.empty, 3=Optional.empty, 4=Optional.empty, 5=Optional.empty, 6=Optional.empty, 7=Optional.empty, 8=Optional.empty, 9=Optional.empty, test1=Optional[测试]}
{0=ERROR:null, 1=ERROR:null, test2=测试2, 2=ERROR:null, 3=ERROR:null, 4=ERROR:null, 5=ERROR:null, 6=ERROR:null, 7=ERROR:null, 8=ERROR:null, 9=ERROR:null, test1=测试}

 

上一篇:Seaborn分布数据可视化---箱型分布图


下一篇:第四章 AlibabaCloud集成Ribbon实现负载均衡