為什么ConcurrentHashMap的key value不能為null,map可以?
源碼
if (key == null || value == null) throw new NullPointerException();
二義性
假定ConcurrentHashMap也可以存放value為null的值。那不管是HashMap還是ConcurrentHashMap調(diào)用map.get(key)的時候,如果返回了null,那么這個null,
都有兩重含義:
1.這個key從來沒有在map中映射過。
2.這個key的value在設(shè)置的時候,就是null。
為什么map允許value=null
對于HashMap的正確使用場景是在單線程下使用。
在單線程中,當(dāng)我們得到的value是null的時候,我可以用hashMap.containsKey(key)方法來區(qū)分上面說的兩重含義。
所以當(dāng)map.get(key)返回的值是null,在HashMap中雖然存在二義性,但是結(jié)合containsKey方法可以避免二義性。
為什么ConcurrentHashMap不允許
ConcurrentHashMap的使用場景為多線程。
用反證法來推理,假設(shè)concurrentHashMap允許存放值為null的value。
這時有A、B兩個線程。
線程A調(diào)用concurrentHashMap.get(key)方法,返回為null,我們還是不知道這個null是沒有映射的null還是存的值就是null。
我們假設(shè)此時返回為null的真實情況就是因為這個key沒有在map里面映射過。那么我們可以用concurrentHashMap.containsKey(key)來驗證我們的假設(shè)是否成立,我們期望的結(jié)果是返回false。
但是在我們調(diào)用concurrentHashMap.get(key)方法之后,containsKey方法之前,有一個線程B執(zhí)行了concurrentHashMap.put(key,null)的操作。那么我們調(diào)用containsKey方法返回的就是true了。這就與我們的假設(shè)的真實情況不符合了。也就是上面說的二義性。
對于key不能為null
源碼就是這樣。。
補充:Hashtable/HashMap與key/value為null的關(guān)系
1、 HashMap計算key的hash值時調(diào)用單獨的方法,在該方法中會判斷key是否為null,如果是則返回0;而Hashtable中則直接調(diào)用key的hashCode()方法,因此如果key為null,則拋出空指針異常。
2、 HashMap將鍵值對添加進數(shù)組時,不會主動判斷value是否為null;而Hashtable則首先判斷value是否為null。
3、以上原因主要是由于Hashtable繼承自Dictionary,而HashMap繼承自AbstractMap。
4、雖然ConcurrentHashMap也繼承自AbstractMap,但是其也過濾掉了key或value為null的鍵值對。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
springboot?web項目中?Set-Cookie?失敗原因及解決辦法
這篇文章主要介紹了springboot?web項目中?Set-Cookie?失敗原因及解決辦法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-10-10
java中volatile和synchronized的區(qū)別與聯(lián)系
這篇文章主要介紹了java中volatile和synchronized的區(qū)別與聯(lián)系的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下2017-10-10
springboot2中session超時,退到登錄頁面方式
這篇文章主要介紹了springboot2中session超時,退到登錄頁面方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
java爬蟲jsoup解析HTML的工具學(xué)習(xí)
jsoup是一個解析HTML的第三方j(luò)ava庫,它提供了一套非常方便的API,可使用DOM,CSS以及類jQuery的操作方法來取出和操作數(shù)據(jù),本文就來開始jsoup的使用學(xué)習(xí)2022-07-07
MyBatis實現(xiàn)多表聯(lián)合查詢resultType的返回值
這篇文章主要介紹了MyBatis多表聯(lián)合查詢resultType的返回值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03

