1. 程式人生 > >HashTable和HashMap的區別詳解

HashTable和HashMap的區別詳解

body 線程安全 serializa javadoc cloneabl 允許 哈希 安全性 rac

HashMap是基於哈希表實現的,每一個元素是一個key-value對,其內部通過單鏈表解決沖突問題,容量不足(超過了閥值)時,同樣會自動增長。

HashMap是非線程安全的,只是用於單線程環境下,多線程環境下可以采用concurrent並發包下的concurrentHashMap。

HashMap 實現了Serializable接口,因此它支持序列化,實現了Cloneable接口,能被克隆。

HashMap存數據的過程是:

HashMap內部維護了一個存儲數據的Entry數組,HashMap采用鏈表解決沖突,每一個Entry本質上是一個單向鏈表。當準備添加一個key-value對時,首先通過hash(key)方法計算hash值,然後通過indexFor(hash,length)求該key-value對的存儲位置,計算方法是先用hash&0x7FFFFFFF後,再對length取模,這就保證每一個key-value對都能存入HashMap中,當計算出的位置相同時,由於存入位置是一個鏈表,則把這個key-value對插入鏈表頭。

HashMap中key和value都允許為null。key為null的鍵值對永遠都放在以table[0]為頭結點的鏈表中。

Hashtable同樣是基於哈希表實現的,同樣每個元素是一個key-value對,其內部也是通過單鏈表解決沖突問題,容量不足(超過了閥值)時,同樣會自動增長。

Hashtable也是JDK1.0引入的類,是線程安全的,能用於多線程環境中。

Hashtable同樣實現了Serializable接口,它支持序列化,實現了Cloneable接口,能被克隆。

Hashtable和HashMap比較相似,感興趣的朋友可以看“Hashtable源碼剖析”這篇博客:http://blog.csdn.net/ns_code/article/details/36191279

下面主要介紹一下HashTable和HashMap區別

三、HashTable和HashMap區別

1、繼承的父類不同

Hashtable繼承自Dictionary類,而HashMap繼承自AbstractMap類。但二者都實現了Map接口。

2、線程安全性不同

javadoc中關於hashmap的一段描述如下:此實現不是同步的。如果多個線程同時訪問一個哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須保持外部同步。

Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情況下是非Synchronize的。在多線程並發的環境下,可以直接使用Hashtable,不需要自己為它的方法實現同步,但使用HashMap時就必須要自己增加同步處理。(結構上的修改是指添加或刪除一個或多個映射關系的任何操作;僅改變與實例已經包含的鍵關聯的值不是結構上的修改。)這一般通過對自然封裝該映射的對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedMap 方法來“包裝”該映射。最好在創建時完成這一操作,以防止對映射進行意外的非同步訪問,如下所示:

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

Hashtable 線程安全很好理解,因為它每個方法中都加入了Synchronize。這裏我們分析一下HashMap為什麽是線程不安全的:

HashMap底層是一個Entry數組,當發生hash沖突的時候,hashmap是采用鏈表的方式來解決的,在對應的數組位置存放鏈表的頭結點。對鏈表而言,新加入的節點會從頭結點加入。

HashTable和HashMap的區別詳解