源碼
if (key == null || value == null) throw new NullPointerException();
二義性
假定ConcurrentHashMap也可以存放value為null的值。那不管是HashMap還是ConcurrentHashMap調用map.get(key)的時候,如果返回了null,那么這個null,都有兩重含義:
1.這個key從來沒有在map中映射過。
2.這個key的value在設置的時候,就是null。
為什么map允許value=null
對於HashMap的正確使用場景是在單線程下使用。
在單線程中,當我們得到的value是null的時候,我可以用hashMap.containsKey(key)方法來區分上面說的兩重含義。
所以當map.get(key)返回的值是null,在HashMap中雖然存在二義性,但是結合containsKey方法可以避免二義性。
為什么ConcurrentHashMap不允許
ConcurrentHashMap的使用場景為多線程。
用反證法來推理,假設concurrentHashMap允許存放值為null的value。
這時有A、B兩個線程。
線程A調用concurrentHashMap.get(key)方法,返回為null,我們還是不知道這個null是沒有映射的null還是存的值就是null。
我們假設此時返回為null的真實情況就是因為這個key沒有在map里面映射過。那么我們可以用concurrentHashMap.containsKey(key)來驗證我們的假設是否成立,我們期望的結果是返回false。
但是在我們調用concurrentHashMap.get(key)方法之后,containsKey方法之前,有一個線程B執行了concurrentHashMap.put(key,null)的操作。那么我們調用containsKey方法返回的就是true了。這就與我們的假設的真實情況不符合了。也就是上面說的二義性。
對於key不能為null
源碼就是這樣。。