HashTable和HashMap的區別詳解
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的區別詳解