h5彩票網(wǎng)站怎么做百度權(quán)重排名查詢
目錄
相同
不同
1. 繼承的父類不同
2. 線程安全性不同
3. 包含的 contains 方法不同
4. toString方法不同
5.?是否允許null值不同
6. 計(jì)算hash值的方式不同
7. 計(jì)算索引位置的方法不同
8. 初始化容量不同
9. 擴(kuò)容方式不同
10. 內(nèi)部存儲(chǔ)策略不同(此處討論的是Java 8)
11. 支持的遍歷種類不同
12. 迭代器不同
相同
HashMap 和 Hashtable 都實(shí)現(xiàn)了 Map、Cloneable、Serializable接口
不同
1. 繼承的父類不同
HashMap 繼承自 AbstractMap 類;
Hashtable 繼承自 Dictionary 類,Dictionary 類是一個(gè)已經(jīng)被廢棄的類,因此已經(jīng)幾乎沒(méi)人用Hashtable 了。
2. 線程安全性不同
HashMap 線程不安全。HashMap 中的方法在一般情況下是非 Synchronize 的。使用 HashMap 時(shí)就必須要自己增加同步處理;
Hashtable 線程安全,內(nèi)部方法大多是 Synchronize 的。在多線程并發(fā)的環(huán)境下,可以直接使用Hashtable,不需要自己為它的方法實(shí)現(xiàn)同步。
Hashtable 實(shí)現(xiàn)線程安全的代價(jià)就是效率變低,因?yàn)闀?huì)鎖住整個(gè) Hashtable,而ConcurrentHashMap 做了相關(guān)優(yōu)化,因?yàn)?ConcurrentHashMap 使用了分段鎖,并不對(duì)整個(gè)數(shù)據(jù)進(jìn)行鎖定,效率比 Hashtable 高很多。
3. 包含的 contains 方法不同
HashMap 是沒(méi)有 contains 方法的,只包括 containsValue 和 containsKey 方法;
Hashtable則保留了 contains 方法,效果同 containsValue,還包括 containsValue 和 containsKey方法。
4. toString方法不同
HashMap沒(méi)有重寫toString()方法;
Hashtable重寫了toString()方法。
5.?是否允許null值不同
HashMap 是允許 key 和 value 為 null 值的,用 containsValue 和 containsKey 方法判斷是否包含對(duì)應(yīng)鍵值對(duì);
Hashtable 鍵值對(duì)都不能為空,會(huì)報(bào)空指針異常。
6. 計(jì)算hash值的方式不同
HashMap 內(nèi)部專門使用了名為 hash 的方法來(lái)對(duì) key 的 hash 值做出進(jìn)一步處理:
(h = key.hashCode()) ^ (h >>> 16),將計(jì)算出的值作為最終的 hash 值。目的是為了獲得一個(gè)更加均勻分布的整數(shù),以便哈希函數(shù)得出的地址更加均勻分布,降低沖突概率;
Hashtable 則是直接使用 key.hashCode() 作為最終的 hash 值。
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
7. 計(jì)算索引位置的方法不同
HashMap 在求 hash 值對(duì)應(yīng)的位置索引為:index = (n - 1) & hash,這樣的取模操作只需要做位運(yùn)算,位運(yùn)算比除法的效率要高很多;
Hashtable:int index = (hash & 0x7FFFFFFF) % tab.length;&0x7FFFFFFF的目的是為了將負(fù)的hash 值轉(zhuǎn)化為正值,因?yàn)?hash 值有可能為負(fù)數(shù),而 &0x7FFFFFFF 后,只有符號(hào)位改變,而后面的位都不變。
8. 初始化容量不同
HashMap 的初始容量為:16
Hashtable 初始容量為:11
但是兩者的負(fù)載因子默認(rèn)都是:0.75。
9. 擴(kuò)容方式不同
HashMap:為原容量的2倍,而且擴(kuò)容結(jié)果一定是2的冪次數(shù);
Hashtable:為原容量2倍加1。
10. 內(nèi)部存儲(chǔ)策略不同(此處討論的是Java 8)
HashMap:滿足鏈表長(zhǎng)度大于等于 8并且數(shù)組長(zhǎng)度大于等于64時(shí),鏈表轉(zhuǎn)變成紅黑樹(shù);當(dāng)紅黑樹(shù)節(jié)點(diǎn)少于6時(shí),退化為鏈表;
Hashtable:都是以鏈表方式存儲(chǔ)。
11. 支持的遍歷種類不同
HashMap 只支持Iterator遍歷;
Hashtable 支持Iterator和Enumeration兩種方式遍歷。
12. 迭代器不同
HashMap 的迭代器(Iterator)是 fail-fast 迭代器;
Hashtable 的enumerator迭代器不是fail-fast的。
所以當(dāng)有其它線程改變了 HashMap 的結(jié)構(gòu)(增加或者移除元素),將會(huì)拋出ConcurrentModificationException,但迭代器本身的 remove() 方法移除元素則不會(huì)拋出ConcurrentModificationException 異常。但這并不是一個(gè)一定發(fā)生的行為,要看 JVM 。而Hashtable 則不會(huì)。
本文參考了下述兩篇文章:
HashMap和Hashtable的區(qū)別(絕對(duì)經(jīng)典)_hashmap hashtable-CSDN博客
HashMap和Hashtable的區(qū)別-CSDN博客