2012-08-16 59 views
22

如JDK文檔中所述,Hashtable不允許空鍵或值。 HashMap允許一個空鍵和任意數量的空值。爲什麼是這樣?爲什麼Hashtable不允許空鍵或值?

+0

因爲密鑰不能在單個映射中複製。 – 2012-08-16 06:38:16

+2

也許這[回答](http://stackoverflow.com/a/7556445/579828)會幫助你。 – Vic 2012-08-16 06:39:35

+4

Hashtable希望通過執行此操作來執行合同。此合約確保當且僅當密鑰不在映射中時,應用於散列表的get(。)方法纔會返回null。 – 2012-08-16 06:40:13

回答

28

散列表是老一類,它的使用通常是不鼓勵的。也許他們看到了需要一個空鍵,更重要的是 - null值,並將其添加到HashMap實現中。

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

編輯

HashtableJavaDoc

爲了成功地存儲和檢索一個Hashtable對象,用作鍵 對象必須實現hashCode方法和equals方法。

由於null不是一個對象,你不能把它.equals().hashCode(),所以Hashtable不能計算散列使用它作爲一個重點。

+15

['ConcurrentHashMap'](http: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html)是一個較新的類,但也有不允許空鍵或值的限制。由於性能方面的原因,它們增加了此限制,因爲支持空鍵和值的工作量很大,但在大多數情況下可能無用。 – DaoWen 2012-08-16 06:45:12

+0

從答案我期待的原因爲什麼哈希表不允許空鍵或值?雖然你建議更新更舊。 – 2017-01-05 04:59:47

3

因爲在HashTable中當你放置一個元素時,它會考慮到鍵值和散列值。基本上你會有這樣的東西:

public Object put(Object key, Object value){ 

key.hashCode(); 

etc... 

value.hashCode(); 

} 

而在HashMap中,如果它爲空,他將根據值計算一個關鍵。不過,我個人不喜歡添加空鍵輸入。

2

原因是接受答案的原因:哈希表是舊的。

但是,在任何情況下,都不鼓勵使用Hashtable而支持HashMap。

  • 散列表是同步的,所以它是THREAD-SAFE。 HashMap不是。

Hashtable和ConcurrentHashMap都不支持空鍵或值。 HashMap可以。

如果您想要一個不需要任何東西而不需要改變類並在任何情況下都能正常工作的插入式替換方法,那麼就不會有任何問題。最相似的選擇將是ConcurrentHashMap(這是線程安全的,但不支持鎖定整個表):

這個類是完全互操作與哈希表中,關於它的線程安全依靠 程序,但不是它的同步細節。

由於同步引入的性能影響,HashMap是單線程應用程序的更好替代品或任何時間同步不是必需品。

來源:

+0

ConcurrentHashMap put:將指定的鍵映射到此表中的指定值。密鑰和值都不能爲空。請檢查你的答案。 – 2016-03-29 13:42:08

+0

哎呀!謝謝你的提醒!我明白並認爲ConcurrentHashMap和HashMap之間的唯一區別是線程安全。這不是第一次發生。多麼尷尬的命名慣例! – NotGaeL 2016-03-30 13:47:28

-1

哈希表 - 不允許null鍵
這是因爲,在放(K鍵,V值)的方法,我們有key.hashcode()其中行空指針異常。
哈希表 - 不允許空值
這是因爲,在放(K鍵,V值)的方法,我們if(value==null){throw new NullPointerException

的HashMap允許空值,因爲它沒有像哈希表的任何檢查,而它只允許一個空鍵。這與putForNullKey方法的幫助下,該值添加到每一次內部數組的第0指數將鍵設置爲空做

+0

類名是java.util.Hashtable而不是「HashTable」! – 2016-08-21 03:50:57

0

因此得出結論

因爲在哈希表,當你把一個元素它將考慮密鑰和值散列。基本上,你會碰到這樣的:

public Object put(Object key, Object value){ 

    key.hashCode(); 

    //some code 

    value.hashCode(); 

} 

哈希表 - 不允許null鍵 這是因爲,在放(K鍵,V值)的方法,我們有key.hashcode(),它拋出空指針異常。 哈希表 - 不允許空值 這是因爲,在放(K鍵,V值)的方法,我們有如果(價值== NULL){拋出新的NullPointerException

的HashMap允許,因爲它沒有空值像HashTable這樣的任何檢查,而它只允許一個null鍵。這與putForNullKey方法的幫助下,該值添加到鍵作爲空提供每次內部數組的第0指數

0

哈希表是非常古老的類,從JDK 1.0

要了解做這首先我們需要理解作者寫在這個類上的評論。 「這個類實現了一個哈希表,它將鍵映射到值。任何非空對象都可以用作鍵或值。 要成功地存儲和從散列表檢索對象,用作鍵的對象必須實現 hashCode方法和equals方法。」

Hashtable類是在散列機制來實現,這意味着存儲任何鍵值對,它需要的關鍵對象的哈希碼。如果密鑰爲空,它將無法給出散列,它將通過空指針異常和類似的情況爲值 如果值爲null,則它將引發null。

但後來發現空鍵和值有其自身的重要性,即 爲什麼在稍後實現的類(如HashMap類)中允許一個空鍵和多個空值。

對於散列映射關鍵字將允許並且如果關鍵字爲null,則存在關鍵字 的空檢查,那麼該元素將被存儲在Entry陣列中的零位置。空鍵我們可以使用一些默認值..

=>哈希表方法是同步的,它永遠不會使用基於對象的鎖定。

HashMap中考慮其特殊

static final int hash(Object key) { 
     int h; 
     return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
    } 

的Java 8,你不能推斷類型哈希表實現。

private Map<String,String> hashtable = new Hashtable<>(); // Not Allowed 

private Map<String,String> hashtable = new HashMap<>(); // Allowed