2013-03-31 71 views
0

大多數同步和併發集合(如HashTable,ConcurrentHashMap等)不允許空值。有空元素有什麼具體問題嗎?帶有同步和併發集合的空元素的問題

+0

您的答案在這裏;)http://stackoverflow.com/questions/7556357/why-does-hashtable-not-take-null-key – Mik378

+0

@ Mik378我已經通過上述討論。這個討論都是關鍵。但在這裏我也在尋找爲什麼在同步和併發收集中不允許空值。 –

+0

ok :)你應該在你的帖子的標題 – Mik378

回答

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

0

這是一個同步圖,接受空鍵和值

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

中對其進行精確的表達,謝謝你的回覆,但是在這裏你正在手動進行同步。但是我在尋找爲什麼它不是同步和併發集合的默認特性。 –

0

從哈希表的JavaDoc:

爲了成功地存儲和檢索從散列表對象,用作鍵 對象必須實現hashCode方法和 equals方法。

概括地說,因爲null不是一個對象,你不能把它.equals()或 .hashCode(),所以Hashtable的無法計算散列使用它作爲 關鍵。

HashMap更新,並且具有更高級的功能,它們基本上只是對Hashtable功能的改進。因此,當創建HashMap時,它被專門設計爲處理空值 作爲鍵,並將它們作爲特殊情況處理。

具體而言,使用空值的作爲密鑰也被類似處理時 發出獲得(鍵):

(?鍵== NULL滿足K == NULL:key.equals(k))的

來源:Why does Hashtable not take null key?

+0

以及爲什麼散列表不允許空值? –

+0

「要成功地從散列表中存儲和檢索對象,用作鍵的對象必須實現hashCode方法和equals方法。」 – Jabir

0

當同步它意味着你將獲得關於該對象或在某些部分鎖。如果你的對象爲null,那麼你將如何決定在哪一部分你將獲得鎖定?

說在concurrenthashmaps,你可以把它分成16個不同的鎖。現在你將如何決定在哪裏放置null?

Null沒有附加值,它只是表示沒有對象。所以爲了避免模棱兩可,最好不要使用它。

1

HashTable.get(key)如果指定的密鑰不在HashTable中,則方法返回null。如果HashTable允許null作爲值,那麼如果我從HashTable.get(key)方法獲得null,則可能有兩種可能性。

  1. 的關鍵是不存在於哈希表
  2. 的關鍵是存在的,但該值集合爲空

它可以是用於API的用戶混亂。 我相信他們不允許空值只是爲了防止這種歧義。

+1

這同樣適用於允許空值的HashMap。 – assylias