背景
最近在梳理總結(jié)《集合 - 常用Map之間區(qū)別》, 其中有一點(diǎn)就是 HashMap 是支持null鍵和null值,而 ConcurrentHashMap 是不支持的;
后來(lái)查看了一下jdk源碼,證明了確實(shí)是這樣的。
HashMap.java 部分源碼
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
ConcurrentHashMap.java 部分源碼
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
......
}
ConcurrentHashMap不能put null 是因?yàn)?無(wú)法分辨是key沒(méi)找到的null還是有key值為null,這在多線程里面是模糊不清的,所以壓根就不讓put null。
ConcurrentHashmap和Hashtable都是支持并發(fā)的,這樣會(huì)有一個(gè)問(wèn)題,當(dāng)你通過(guò)get(k)獲取對(duì)應(yīng)的value時(shí),如果獲取到的是null時(shí),你無(wú)法判斷,它是put(k,v)的時(shí)候value為null,還是這個(gè)key從來(lái)沒(méi)有做過(guò)映射。HashMap是非并發(fā)的,可以通過(guò)contains(key)來(lái)做這個(gè)判斷。而支持并發(fā)的Map在調(diào)用m.contains(key)和m.get(key),m可能已經(jīng)不同了。