美團太細了,HashMap可以存Null,ConcurrentHashMap不可以,為什么?
我們知道,ConcurrentHashMap在使用時,和HashMap有一個比較大的區(qū)別,那就是HashMap中,null可以作為鍵或者值都可以。而在ConcurrentHashMap中,key和value都不允許為null。
那么,為什么呢?為啥ConcurrentHashMap要設(shè)計成這樣的呢?
關(guān)于這個問題,其實最有發(fā)言權(quán)的就是ConcurrentHashMap的作者——Doug Lea。
他自己曾經(jīng)出面解釋過這個問題,內(nèi)容如下(原文地址已經(jīng)打不開了,大家將就著看一下截圖吧) :
主要意思就是說:
ConcurrentMap(如ConcurrentHashMap、ConcurrentSkipListMap)不允許使用null值的主要原因是,在非并發(fā)的Map中(如HashMap),是可以容忍模糊性(二義性)的,而在并發(fā)Map中是無法容忍的。
假如說,所有的Map都支持null的話,那么map.get(key)就可以返回null,但是,這時候就會存在一個不確定性,當你拿到null的時候,你是不知道他是因為本來就存了一個null進去還是說就是因為沒找到而返回了null。
在HashMap中,因為它的設(shè)計就是給單線程用的,所以當我們map.get(key)返回null的時候,我們是可以通過map.contains(key)檢查來進行檢測的,如果它返回true,則認為是存了一個null,否則就是因為沒找到而返回了null。
但是,像ConcurrentHashMap,它是為并發(fā)而生的,它是要用在并發(fā)場景中的,當我們map.get(key)返回null的時候,是沒辦法通過通過map.contains(key)檢查來準確的檢測,因為在檢測過程中可能會被其他線程鎖修改,而導(dǎo)致檢測結(jié)果并不可靠。
所以,為了讓ConcurrentHashMap的語義更加準確,不存在二義性的問題,他就不支持null。