具有同步和并发集合的null元素的问题

时间:2013-03-31 16:31:14

标签: java collections concurrency synchronization

大多数同步和并发集合(如HashTable,ConcurrentHashMap等)不允许空值。 null元素是否有任何特定问题?

5 个答案:

答案 0 :(得分:1)

如果HashTable中不存在指定的键,则

HashTable.get(key)方法返回null。如果HashTable允许null作为值,那么如果我从HashTable.get(key)方法获得null,则有两种可能性。

  1. 密钥在HashTable中不存在
  2. 密钥存在,但值集为空
  3. API的用户可能会感到困惑。 我相信他们不允许空值只是为了防止这种歧义。

答案 1 :(得分:1)

Hashtable有点过时,所以我不会评论它。对于ConcurrentHashMap,API与标准HashMap的重要补充之一是一些原子方法,例如putIfAbsent。的Javadoc:

  

返回与指定键关联的先前值,如果没有键的映射

,则返回null

特别是,如果地图允许使用null键,则使用该方法会更复杂。您需要确保无法覆盖值的典型模式是:

ConcurrentMap<K,V> map = new ConcurrentHashMap<> ();
V value = map.get(key);
if (value == null) {
    value = new V();
    V previousValue = map.putIfAbsent(key, value);
    if (previousValue != null) { //Here you need to be sure what that means
        value = previousValue;
    }
}
useValue(value);

另一个例子是你如何检查一个键是否在HashMap中(并且你需要返回值):

V value = map.get(key);
if (value == null && !map.containsKey(key)) {
}

并发环境中的问题是整个事情不是原子的。

另请参阅this postthese comments by the author of CHM

答案 2 :(得分:0)

这是一个接受空键和值的同步映射

    Map m = Collections.synchronizedMap(new HashMap());

答案 3 :(得分:0)

  

来自Hashtable JavaDoc:

     

要成功存储和检索哈希表中的对象,   用作键的对象必须实现hashCode方法和   等于方法。

     

简而言之,由于null不是对象,因此无法调用.equals()或   .hashCode()就可以了,所以Hashtable无法计算哈希来使用它   一把钥匙。

     

HashMap更新,并且具有更多高级功能   基本上只是对Hashtable功能的改进。因此,   在创建HashMap时,它专门用于处理null   将值作为键并将其作为特殊情况处理。

     

具体来说,使用null作为键是这样处理的   发出.get(密钥):

     

(key == null?k == null:key.equals(k))

来源:Why does Hashtable not take null key?

答案 4 :(得分:0)

同步时,意味着您将获得该对象或某个部分的锁定。如果您的对象为null,那么您将如何决定在哪个部分获得锁定?

在concurrenthashmaps中说,你可以把它分成16个不同的锁。现在您将如何确定将放置null的位置?

Null没有附加值,它只是意味着没有对象。所以为了避免歧义,最好不要拥有它。