【Java基礎】ConcurrentHashMap為什么不能存null鍵和null值


代碼如下

    /**
     * 測試ConcurrentHashMap null鍵和null值的問題
     * @return
     */
    @RequestMapping(value = "/get_nacos")
    public String getNacos(){
        ConcurrentHashMap<String,String> map =new ConcurrentHashMap<>(1);
        map.put("testKey", null);
        String nullValue = map.get("sss");
        return nullValue;
    }
}

其中在執行put操作時,會報錯,信息如下:

java.lang.NullPointerException: null
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011) ~[na:1.8.0_162]
    at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006) ~[na:1.8.0_162]
    at com.gabriel.stage.controller.TestController.getNacos(TestController.java:44) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.1.7.RELEASE.jar:5.1.7.RELEASE]

那么這里就有一個疑問了,為什么HashMap能存null鍵和null值,ConcurrentHashMap就不能存null鍵和null值了呢,並且還會出現空指針異常

個人理解如下:

  ConrrentHashMap 是一個用於多線程並發場景下的並發容器(Map),也就是在多線程環境下執行增刪改查方法要保證線程安全性,

  例如containsKey()方法中

    public boolean containsKey(Object key) {
        return get(key) != null;
    }

  該方法會調用get方法去查詢key值是否存在,此時如果key值是我們手動存進去的,這個時候就會在代碼語義上有區別,無法區分是真的沒有該key 還是我們存儲的key,

  並且在調用get()方法時,可能會出現別的線程修改為null鍵和null值的情況,這中情況在並發場景下會產生歧義;

  

   HashMap本身是一個線程不安全的容器(Map),也就是使用場景局限於單線程環境,因此存儲null鍵null值 通常不會有什么問題,

   HashMap將存儲的null鍵存儲到數組的第1個元素;

 


免責聲明!

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



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