目前我使用的是ConcurrentHashMap
,并且我非常熟悉HashMap
,我预计会有类似于HashMap
的行为,但当我插入null
键或值时,ConcurrentHashMap
会抛出NullPointerException
。
我看到了他们的来源,ConcurrentHashMap
的片段:
...
public V put(K key, V value) {
return putVal(key, value, false);
}
...
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
....
而HashMap
的片段:
...
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
...
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
// It Doesn't check null key or value.
....
为什么它们在使用null
键或值时如此不同?这对我来说没有意义。
您可以参考Doug Lea的评论:
ConcurrentMaps(ConcurrentHashMaps,ConcurrentSkipListMaps)中不允许null的主要原因是无法容纳在非并发映射中几乎无法容忍的模糊性。主要的一点是,如果map.get(key)返回null,则无法检测该键是否显式映射为null,而该键是否未映射。在非并发映射中,您可以通过map.contains(key)来检查这一点,但在并行映射中,映射可能在调用之间发生了更改。
从文档中可以看到:
这个类及其视图和迭代器实现了所有可选的Map和Iterator接口的方法。
与Hashtable类似,但与HashMap不同,此类不允许null用作键或值。
此类是Java Collections Framework的成员。