HashMap與HashTable聯繫與區別

HashMapHashTablejava

1.hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法。
2.hashTable同步的,而HashMap是非同步的,效率上比hashTable要高,HashMap不是線程安全的 ,HashTable是線程安全的一個Collection。
3.hashMap容許空鍵值,而hashTable不容許。算法

ashtable繼承自Dictionary類,而HashMap是Map接口的一個實現。這裏要說明一下Dictionary類是jdk1.0中就有的,而Map接口是1.2以後纔有的,固然與此同時Hashtable也實現了Map接口。數組

HashTable的應用很是普遍,HashMap是新框架中用來代替HashTable的類,也就是說建議使用HashMap,不要使用HashTable。可能你以爲HashTable很好用,爲何不用呢?這裏簡單分析他們的區別。 安全

1.HashTable的方法是同步的,HashMap未經同步,因此在多線程場合要手動同步HashMap這個區別就像Vector和ArrayList同樣。多線程

2.HashTable不容許null值(key和value都不能夠),HashMap容許null值(key和value均可以)。框架

3.HashTable有一個contains(Object value),功能和containsValue(Object value)功能同樣。 函數

4.HashTable使用Enumeration,HashMap使用Iterator。spa

以上只是表面的不一樣,它們的實現也有很大的不一樣。線程

5.HashTable中hash數組默認大小是11,增長的方式是 old*2+1。HashMap中hash數組的默認大小是16,並且必定是2的指數。對象

6.哈希值的使用不一樣,HashTable直接使用對象的hashCode,代碼是這樣的:

int hash = key.hashCode();

int index = (hash & 0x7FFFFFFF) % tab.length;

而HashMap從新計算hash值,並且用與代替求模:

int hash = hash(k);

int i = indexFor(hash, table.length);

 

static int hash(Object x) {

  int h = x.hashCode();

 

  h += ~(h << 9);

  h ^= (h >>> 14);

  h += (h << 4);

  h ^= (h >>> 10);

  return h;

}

static int indexFor(int h, int length) {

  return h & (length-1);

}

 

HashMap和Hashtable的相同點

HashMapHashtable都是存儲「鍵值對(key-value)」的散列表,並且都是採用拉鍊法實現的。
存儲的思想都是:經過table數組存儲,數組的每個元素都是一個Entry;而一個Entry就是一個單向鏈表Entry鏈表中的每個節點就保存了key-value鍵值對數據

 

添加key-value鍵值對:首先,根據key值計算出哈希值,再計算出數組索引(即,該key-value在table中的索引)。而後,根據數組索引找到Entry(即,單向鏈表),再遍歷單向鏈表,將key和鏈表中的每個節點的key進行對比。若key已經存在Entry鏈表中,則用該value值取代舊的value值;若key不存在Entry鏈表中,則新建一個key-value節點,並將該節點插入Entry鏈表的表頭位置。
刪除key-value鍵值對:刪除鍵值對,相比於「添加鍵值對」來講,簡單不少。首先,仍是根據key計算出哈希值,再計算出數組索引(即,該key-value在table中的索引)。而後,根據索引找出Entry(即,單向鏈表)。若節點key-value存在與鏈表Entry中,則刪除鏈表中的節點便可。

HashMap和Hashtable的不一樣點

1 繼承和實現方式不一樣

HashMap 繼承於AbstractMap,實現了Map、Cloneable、java.io.Serializable接口。
Hashtable 繼承於Dictionary,實現了Map、Cloneable、java.io.Serializable接口。

2 線程安全不一樣

Hashtable的幾乎全部函數都是同步的,即它是線程安全的,支持多線程。
而HashMap的函數則是非同步的,它不是線程安全的。 若要在多線程中使用HashMap,須要咱們額外的進行同步處理。 對HashMap的同步處理可使用Collections類提供的synchronizedMap靜態方法,或者直接使用JDK 5.0以後提供的java.util.concurrent包裏的ConcurrentHashMap類。

3 對null值的處理不一樣

HashMap的key、value均可覺得null
Hashtable的key、value都不能夠爲null

Hashtable的key或value,都不能爲null!不然,會拋出異常NullPointerException。
HashMap的key、value均可覺得null。 當HashMap的key爲null時,HashMap會將其固定的插入table[0]位置(即HashMap散列表的第一個位置);並且 table[0]處只會容納一個key爲null的值,當有多個key爲null的值插入的時候,table[0]會保留最後插入的value。

4 支持的遍歷種類不一樣

HashMap只支持Iterator(迭代器)遍歷。
而Hashtable支持Iterator(迭代器)和Enumeration(枚舉器)兩種方式遍歷。

5 經過Iterator迭代器遍歷時,遍歷的順序不一樣

HashMap是「從前向後」的遍歷數組;再對數組具體某一項對應的鏈表,從表頭開始進行遍歷。
Hashtable是「從後往前」的遍歷數組;再對數組具體某一項對應的鏈表,從表頭開始進行遍歷。

6 容量的初始值 和 增長方式都不同

HashMap默認的容量大小是16;增長容量時,每次將容量變爲「原始容量x2」
Hashtable默認的容量大小是11;增長容量時,每次將容量變爲「原始容量x2 + 1」。

7 添加key-value時的hash值算法不一樣

HashMap添加元素時,是使用自定義的哈希算法。
Hashtable沒有自定義哈希算法,而直接採用的key的hashCode()。

 

HashMap和WeakHashMap的相同點

1 它們都是散列表,存儲的是「鍵值對」映射。
2 它們都繼承於AbstractMap,而且實現Map基礎。
3 它們的構造函數都同樣。
   它們都包括4個構造函數,並且函數的參數都同樣。
4 默認的容量大小是16,默認的加載因子是0.75。
5 它們的「鍵」和「值」都容許爲null。
6 它們都是「非同步的」。

HashMap和WeakHashMap的不一樣點

1 HashMap實現了Cloneable和Serializable接口,而WeakHashMap沒有。

2 HashMap的「鍵」是「強引用(StrongReference)」,而WeakHashMap的鍵是「弱引用(WeakReference)」。

相關文章
相關標籤/搜索