JDK HashTable詳解

先上HashTable的繼承關(guān)系:


HashTable繼承關(guān)系圖

為了方便比較同時(shí)放出HashMap的繼承關(guān)系:

HashMap的繼承關(guān)系

可以看出HahMap和HashTable都實(shí)現(xiàn)了Map接口,只是父類(lèi)不一樣

HashTable的計(jì)算哈希是直接取得key本身的哈希:

  int hash = key.hashCode();

這里可以看出纹冤,hashtable是不支持null值的芬迄,并且在put的時(shí)候取哈希之前已經(jīng)判定了value為空判定于样,雖然key沒(méi)有判定,但是在取hash的時(shí)候由于key是null所以一定會(huì)拋出java.lang.NullPointerException

if (value == null) {
throw new NullPointerException();
}

HashTable每次擴(kuò)容是原有容量的2倍+1( (oldCapacity << 1) + 1),通過(guò)rehash()來(lái)實(shí)現(xiàn)擴(kuò)容的

HashTable是的每個(gè)哈希桶的元素都是鏈表,相對(duì)來(lái)說(shuō)如果每個(gè)哈希桶元素比較多的話萨西,處理效率是比較低的如输,接下來(lái)劃重點(diǎn)鼓黔,這實(shí)質(zhì)就是哈希表的實(shí)質(zhì),一張課表


課表

我們首先取得今天的日期不见,比如星期三澳化,然后一節(jié)一節(jié)比較,尋找文體活動(dòng)這門(mén)課稳吮,畢竟大家都不喜歡上課缎谷,過(guò)程和HashTable完全一致

哈希桶就相當(dāng)于一個(gè)表格,首先從X軸取得哈希桶位置再在Y軸比較獲取元素真實(shí)位置灶似。

HashTable的計(jì)算索引的方式是:

 (hash & 0x7FFFFFFF) % tab.length
這里為什么要與0x7FFFFFFF是因?yàn)镠ash的值會(huì)是負(fù)數(shù)列林,0x7FFFFFFF是Integer.MAX_VALUE,使用Math.abs()也可以達(dá)到想用的效果,但是為什么不用它呢

主要原因如下圖所示:


0x7FFFFFFF 和Math.abs()的區(qū)別

計(jì)算結(jié)果

可以看到當(dāng)hash為Integer的最小值的時(shí)候酪惭,會(huì)導(dǎo)致Math.abs取得負(fù)數(shù)值希痴,這樣計(jì)算出來(lái)的index下標(biāo)也是負(fù)值,而java的數(shù)組下標(biāo)不能為負(fù)數(shù)春感,否則會(huì)導(dǎo)致程序異常

最終將node追加到哈希哈希桶某個(gè)哈西位置的尾部砌创,就完成了整個(gè)存儲(chǔ)過(guò)程

需要注意的是:HashTable是線程安全的,HashTable所有public方法都添加了synchronized關(guān)鍵字鲫懒,保證線程同步不會(huì)出錯(cuò)嫩实。但是同時(shí)因?yàn)榫€程安全機(jī)制導(dǎo)致HashTable的存取效率不如HashMap

比較上一篇文章 JDK HashMap詳解 而言,HashTable雖然都實(shí)現(xiàn)了Map接口窥岩,但各自有著不同的應(yīng)用場(chǎng)景甲献,總結(jié)起來(lái)有如下不同點(diǎn):

  • HashTable是線程安全的,HashMap是線程不安全的
  • HashTable允許K,V均可以為null谦秧,但是HashMap不能為null竟纳,否則會(huì)有空指針異常
  • 計(jì)算Hash的方式不同,HashTable計(jì)算哈希的方式是直接取key本身的hash疚鲤,而HashMap計(jì)算hash的方式為:(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16) 自身哈希和哈希無(wú)符號(hào)右移16位做與運(yùn)算锥累,之所以會(huì)有這種差異是因?yàn)镠ashTable和HashTable計(jì)算索引方式不同,HashTable直接與當(dāng)前長(zhǎng)度取余獲取當(dāng)前索引集歇,而HashMap通過(guò)公式((size - 1) & hash)計(jì)算索引值
  • 數(shù)據(jù)結(jié)構(gòu)不同:HashTable采用的是鏈表形式桶略,而HashMap采用的是閾值以下用鏈表閾值以上用紅黑樹(shù)的數(shù)據(jù)結(jié)構(gòu)
  • 存取效率:HashTable的效率相對(duì)比較低,因?yàn)橛衧ynchronized關(guān)鍵字做線程同步,HashMap存取效率比較高际歼,因?yàn)闆](méi)有鎖的限制惶翻,但因?yàn)槠洳皇蔷€程安全的,在線程安全場(chǎng)景下需要進(jìn)行一些線程同步操作
  • 在查詢包含關(guān)系的時(shí)候鹅心,HashTable提供的是contains(),containsKey()和containsValue()方法吕粗,而hashMap把只有兩個(gè)分別為:containsKey()和containsValue()
  • HashTable是官方建議被替換的以下來(lái)自于JDK8中的注釋

If a thread-safe implementation is not needed, it is recommended to use
{@link HashMap} in place of {@code Hashtable}. If a thread-safe
highly-concurrent implementation is desired, then it is recommended
to use {@link java.util.concurrent.ConcurrentHashMap} in place of
{@code Hashtable}.
大致含義為:如果你不需要線程同步,建議使用HashMap來(lái)代替HashTable旭愧,如果你的你是需要線程同步的話使用ConcurrentHashMap來(lái)替代Hashtable

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颅筋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子输枯,更是在濱河造成了極大的恐慌议泵,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桃熄,死亡現(xiàn)場(chǎng)離奇詭異先口,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瞳收,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)碉京,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人缎讼,你說(shuō)我怎么就攤上這事收夸。” “怎么了血崭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵卧惜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我夹纫,道長(zhǎng)咽瓷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任舰讹,我火速辦了婚禮茅姜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘月匣。我一直安慰自己钻洒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布锄开。 她就那樣靜靜地躺著素标,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萍悴。 梳的紋絲不亂的頭發(fā)上头遭,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天寓免,我揣著相機(jī)與錄音,去河邊找鬼计维。 笑死袜香,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鲫惶。 我是一名探鬼主播蜈首,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼剑按!你這毒婦竟也來(lái)了疾就?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤艺蝴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鸟废,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體猜敢,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年盒延,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缩擂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡添寺,死狀恐怖胯盯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情计露,我是刑警寧澤博脑,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站票罐,受9級(jí)特大地震影響叉趣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜该押,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一疗杉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蚕礼,春花似錦烟具、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至罩润,卻和暖如春玖翅,著一層夾襖步出監(jiān)牢的瞬間翼馆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工金度, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留应媚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓猜极,卻偏偏與公主長(zhǎng)得像中姜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跟伏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • HashMap 是 Java 面試必考的知識(shí)點(diǎn)丢胚,面試官?gòu)倪@個(gè)小知識(shí)點(diǎn)就可以了解我們對(duì) Java 基礎(chǔ)的掌握程度。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,669評(píng)論 9 107
  • Java8張圖 11受扳、字符串不變性 12携龟、equals()方法、hashCode()方法的區(qū)別 13勘高、...
    Miley_MOJIE閱讀 3,709評(píng)論 0 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法峡蟋,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法华望,繼承相關(guān)的語(yǔ)法蕊蝗,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,665評(píng)論 18 399
  • 一、基本數(shù)據(jù)類(lèi)型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類(lèi)型而言...
    龍貓小爺閱讀 4,268評(píng)論 0 16
  • 千彎百轉(zhuǎn)九天上宾抓,連云寺上連云天子漩。 東塘北塘收眼底,庇佑漳河福綿綿洞慎。
    跡遠(yuǎn)留香閱讀 741評(píng)論 0 0