在使用 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=測試}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM