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 來替代。
————————————————
版權宣告:本文為CSDN博主「華-山」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/mountain_hua/article/details/81193887