HashMap和HashTable的異同

比較 HashMap HashTable

存儲結構

數組 + 鏈表/紅黑樹 數組 + 鏈表

擴容方式

oldCap * 2 oldCap * 2 + 1
K,V能否爲null key, value 均可以爲 null key, value 均不可以爲 null

線程是否安全

線程不安全 線程安全

HashMap的存儲規則:

優先使用數組存儲, 如果出現Hash衝突, 將在數組的該位置拉伸出鏈表進行存儲(在鏈表的尾部進行添加), 如果鏈表的長度大於設定值後, 將鏈表轉爲紅黑樹。

擴容方式:

Hashtable默認的初始大小爲11,之後每次擴充,容量變爲原來的2n+1。HashMap默認的初始化大小爲16。之後每次擴充,容量變爲原來的2倍。

創建時,如果給定了容量初始值,那麼Hashtable會直接使用你給定的大小,而HashMap會將其擴充爲2的冪次方大小。也就是說Hashtable會盡量使用素數、奇數。而HashMap則總是使用2的冪作爲哈希表的大小。

之所以會有這樣的不同,是因爲Hashtable和HashMap設計時的側重點不同。Hashtable的側重點是哈希的結果更加均勻,使得哈希衝突減少。當哈希表的大小爲素數時,簡單的取模哈希的結果會更加均勻。而HashMap則更加關注hash的計算效率問題。在取模計算時,如果模數是2的冪,那麼我們可以直接使用位運算來得到結果,效率要大大高於做除法。HashMap爲了加快hash的速度,將哈希表的大小固定爲了2的冪。當然這引入了哈希分佈不均勻的問題,所以HashMap爲解決這問題,又對hash算法做了一些改動。這從而導致了Hashtable和HashMap的計算hash值的方法不同 

關於線程安全問題:

Hashtable是線程安全的,它的每個方法中都加入了Synchronize方法。在多線程併發的環境下,可以直接使用Hashtable,不需要自己爲它的方法實現同步

HashMap不是線程安全的,在多線程併發的環境下,可能會產生死鎖等問題。使用HashMap時就必須要自己增加同步處理,

雖然HashMap不是線程安全的,但是它的效率會比Hashtable要好很多。這樣設計是合理的。在我們的日常使用當中,大部分時間是單線程操作的。HashMap把這部分操作解放出來了。當需要多線程操作的時候可以使用線程安全的ConcurrentHashMap。ConcurrentHashMap雖然也是線程安全的,但是它的效率比Hashtable要高好多倍。因爲ConcurrentHashMap使用了分段鎖,並不對整個數據進行鎖定。

另外:Hashtable 基本已經被棄用,在 Java 5 之後用 ConcurrentHashMap 來替代。

參考資料:https://blog.csdn.net/charmingwong/article/details/71503459

                  https://blog.csdn.net/wangxing233/article/details/79452946

                  https://www.cnblogs.com/wuqinglong/p/5746473.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章