HashMap和Hashtable的詳細(xì)比較
HashMap和Hashtable的詳細(xì)比較
前言:
可以直接根據(jù)hashcode值判斷兩個(gè)對(duì)象是否相等嗎?肯定是不可以的,因?yàn)椴煌膶?duì)象可能會(huì)生成相同的hashcode值。雖然不能根據(jù)hashcode值判斷兩個(gè)對(duì)象是否相等,但是可以直接根據(jù)hashcode值判斷兩個(gè)對(duì)象不等,如果兩個(gè)對(duì)象的hashcode值不等,則必定是兩個(gè)不同的對(duì)象。如果要判斷兩個(gè)對(duì)象是否真正相等,必須通過equals方法。
也就是說對(duì)于兩個(gè)對(duì)象,如果調(diào)用equals方法得到的結(jié)果為true,則兩個(gè)對(duì)象的hashcode值必定相等;如果equals方法得到的結(jié)果為false,則兩個(gè)對(duì)象的hashcode值不一定不同;如果兩個(gè)對(duì)象的hashcode值不等,則equals方法得到的結(jié)果必定為false;如果兩個(gè)對(duì)象的hashcode值相等,則equals方法得到的結(jié)果未知。
HashMap和Hashtable不保證map的順序,也不保證順序不會(huì)隨著時(shí)間不變。
HashMap實(shí)例有兩個(gè)參數(shù)影響性能:初始capacity和load factor。capacity是hashtable中桶的數(shù)量,初始capacity就是hashtable創(chuàng)建時(shí)的capacity。load factor影響hashtable多滿時(shí)允許自動(dòng)增加capacity。當(dāng)hashtable中entry的數(shù)量超過load factor和當(dāng)前capacity的乘積,hashtable會(huì)重新哈希(意味著,內(nèi)部數(shù)據(jù)結(jié)構(gòu)重建)因此hashtable大約擁有桶數(shù)量的兩倍。
作為通用規(guī)則,默認(rèn)load factor(0.75)在時(shí)間和空間消耗上提供了好的權(quán)衡。值越大,空間開銷越小,但是遍歷成本增加(表現(xiàn)在大多數(shù)操作,包括get和put)。當(dāng)設(shè)置初始capacity時(shí),為了最小化重新hash的操作次數(shù),應(yīng)該考慮map的entry數(shù)量和load factor。如果初始容量大于最大entry數(shù)量除以load factor,重新hash操作將不會(huì)發(fā)生。然而,設(shè)置初始capacity太大會(huì)浪費(fèi)空間。
如果許多mapping存儲(chǔ)在HashMap實(shí)例中,創(chuàng)建時(shí)使用足夠大的capacity將允許mapping存儲(chǔ)得更有效率,因?yàn)椴粫?huì)隨著table的數(shù)量增大重新hash。注意使用許多相同hashCode()的key肯定會(huì)降低任意hashtable的性能。
二.相同點(diǎn)
DEFAULT_LOAD_FACTOR |
0.75 |
TREEIFY_THRESHOLD |
8 |
UNTREEIFY_THRESHOLD |
6 |
MIN_TREEIFY_CAPACITY 否則resize() |
64 |
size |
mapping數(shù)量 |
threhold |
capacity*load factor |
三.不同點(diǎn)
|
Hashtable |
|
線程安全 |
不安全 |
安全 |
允許null的鍵和值 |
允許 |
不允許 |
實(shí)現(xiàn)和繼承 |
實(shí)現(xiàn)Map |
實(shí)現(xiàn)Map,繼承Dictionary |
遍歷方式 |
Iterator |
Iterator和Enumeration |
計(jì)算哈希值 |
(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16) |
(key.hashCode() & 0x7FFFFFFF) |
計(jì)算數(shù)組下標(biāo) |
(length - 1) & hash |
hash % length |
DEFAULT_INITIAL_CAPACITY |
16 |
11 |
容量增加方式 |
old*2 長度始終為2的冪 |
old*2+1 |
構(gòu)造函數(shù) |
threshold=tableSizeFor(initialCapacity) |
threhold=initialCapacity*load factor |
resize |
從0-cap 鏈表順序不變 |
從cap-0 鏈表順序相反 |
計(jì)算數(shù)組下標(biāo):當(dāng)length總是2的n次方時(shí),h&(length-1)運(yùn)算等價(jià)于對(duì)length取模,也就是h%length,但是&比%具有更高的效率。
容量增加方式:當(dāng)數(shù)組長度為2的n次冪的時(shí)候,不同的key算得的index相同的幾率較小,那么數(shù)據(jù)在數(shù)組上分布就比較均勻,也就是說碰撞的幾率小。相對(duì)的,查詢的時(shí)候就不用遍歷某個(gè)位置上的鏈表,這樣查詢效率也就較高了。導(dǎo)致resize()不同HashMap直接使用之前的數(shù)組下表,而Hashtable需要重新計(jì)算。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- java HashMap和HashTable的區(qū)別詳解
- java面試題——詳解HashMap和Hashtable 的區(qū)別
- HashMap 和 Hashtable的區(qū)別
- Java中Hashtable類與HashMap類的區(qū)別詳解
- Java中HashMap和Hashtable的區(qū)別淺析
- Java中HashMap和Hashtable及HashSet的區(qū)別
- 淺析Java中Map與HashMap,Hashtable,HashSet的區(qū)別
- 淺析java中ArrayList與Vector的區(qū)別以及HashMap與Hashtable的區(qū)別
- java中Hashtable和HashMap的區(qū)別分析
- HashMap和HashTable底層原理以及常見面試題
相關(guān)文章
Java實(shí)現(xiàn)多項(xiàng)式除法的代碼示例
今天小編就為大家分享一篇關(guān)于Java實(shí)現(xiàn)多項(xiàng)式除法的代碼示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10Spring boot + mybatis + Vue.js + ElementUI 實(shí)現(xiàn)數(shù)據(jù)的增刪改查實(shí)例代碼(一)
這篇文章主要介紹了Spring boot + mybatis + Vue.js + ElementUI 實(shí)現(xiàn)數(shù)據(jù)的增刪改查實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05Java?IO篇之Reactor?網(wǎng)絡(luò)模型的概念
Reactor?模式也叫做反應(yīng)器設(shè)計(jì)模式,是一種為處理服務(wù)請(qǐng)求并發(fā)提交到一個(gè)或者多個(gè)服務(wù)處理器的事件設(shè)計(jì)模式,Reactor?模式主要由?Reactor?和處理器?Handler?這兩個(gè)核心部分組成,本文給大家介紹Java?IO篇之Reactor?網(wǎng)絡(luò)模型的概念,感興趣的朋友一起看看吧2022-01-01簡單介紹區(qū)分applet和application的方法
applet和application都是Java語言編寫出來的應(yīng)用程序,本文簡單介紹了二者的不同之處,需要的朋友可以參考下2017-09-09Mybatis實(shí)現(xiàn)Mapper動(dòng)態(tài)代理方式詳解
這篇文章主要為大家詳細(xì)介紹了Mybatis實(shí)現(xiàn)Mapper動(dòng)態(tài)代理方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08解析SpringBoot @EnableAutoConfiguration的使用
這篇文章主要介紹了解析SpringBoot @EnableAutoConfiguration的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09