HashMap工作原理

最近參與公司的實(shí)習(xí)生招聘工作窒盐,面試了幾位實(shí)習(xí)生,我有一道每次面試都必問(wèn)的題目【HasmMap的工作原理】,但很遺憾挑社,至今還沒(méi)遇到令我完全滿意的回答。今天這篇文章就來(lái)回答下HashMap相關(guān)的面試題巡揍。


1. 什么是HashMap痛阻?

java.util.HashMap是Java語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的一個(gè)容器類,主要用來(lái)存儲(chǔ)鍵值對(duì)腮敌。是數(shù)據(jù)結(jié)構(gòu)中哈希表在Java語(yǔ)言的一個(gè)實(shí)現(xiàn)录平。

哈希表是數(shù)據(jù)結(jié)構(gòu)中的一個(gè)概念麻车,可以存儲(chǔ)n個(gè)元素,取元素的時(shí)間復(fù)雜度為O(1).

一般情況下斗这,從n個(gè)元素中查找一個(gè)元素动猬,時(shí)間復(fù)雜度為O(n). 為何哈希表能有O(1)的時(shí)間復(fù)雜度?

因?yàn)樵卦诖鎯?chǔ)時(shí)已經(jīng)大致確定了位置表箭,查找的時(shí)候可以定位到對(duì)應(yīng)的位置赁咙,因此時(shí)間復(fù)雜度為O(1).

2. HashMap中的數(shù)據(jù)結(jié)構(gòu)

HashMap使用數(shù)組+鏈表的方式實(shí)現(xiàn)。

數(shù)組的作用主要是定位元素位置免钻。

鏈表的作用是解決哈希沖突問(wèn)題彼水。遇到hash值相等的key,就把相應(yīng)鍵值使用鏈表的方式全部保存下來(lái)极舔。

3. put操作

put方法定義

public V put(K key, V value)

put操作執(zhí)行過(guò)程:

a. 計(jì)算key的hashcode

b. 根據(jù)hashcode計(jì)算出需要將該鍵值對(duì)存儲(chǔ)的位置-即桶的位置

c. 找到桶的位置后凤覆,如果桶未被占用,則存入該鍵值對(duì)拆魏;若桶中已有數(shù)據(jù)盯桦,則需要遍歷桶中數(shù)據(jù),并且比較key的equals方法渤刃。遇到key相同的拥峦,則用新的value,把舊值替換掉(put操作會(huì)將舊值覆蓋掉)卖子。若沒(méi)找到略号,則將該鍵值對(duì)存儲(chǔ)在鏈表的末尾。

4. get操作

get方法定義

public V get(Object key)

get操作執(zhí)行過(guò)程:

a. 計(jì)算key的hashcode

b. 根據(jù)hashcode洋闽,定位該元素所在桶的位置

c. 若桶為空玄柠,則返回null;若桶不空诫舅,則遍歷桶中數(shù)據(jù)随闪,比較key的equals方法,若遇到相同的元素骚勘,則返回對(duì)于的value中铐伴;沒(méi)遇到,則返回null

5. 什么樣的類型可以作為HashMap的key俏讹?

a. 重寫hashCode() 和 equals() 方法

HashMap在get/put數(shù)據(jù)時(shí)当宴,需要調(diào)用hashCode() 和 equals() 方法,因此只有重寫了hashCode() 和 equals() 方法的類泽疆,才可以作為HashMap的key户矢。

(hashCode相同,對(duì)象不一定相等殉疼;對(duì)象相等梯浪,則hashCode必然相同)

b. 不可變性

不可變性也是必要的捌年,若元素可變,則相應(yīng)hashCode也會(huì)發(fā)生變化挂洛,調(diào)用get()方法時(shí)礼预,可能找不到相應(yīng)的value,甚至可能找到錯(cuò)誤的value虏劲。

6. 如何計(jì)算數(shù)組下標(biāo)

在JDK1.8之前的版本中托酸,是通過(guò)key的hashCode()進(jìn)行hashing,然后將( n-1 & hash)來(lái)確定數(shù)組下標(biāo)柒巫,即桶的位置励堡。

在JDK1.8版本,將hash值的高16位與低16位進(jìn)行異或

JDK 1.8:

(h = key.hashCode()) ^ (h >>>16)

這樣做的目的主要是為了減少哈希沖突的可能性堡掏。特別是數(shù)據(jù)量較小時(shí)应结,舊的計(jì)算方式哈希沖突的可能比較大。

7. HashMap的兩個(gè)重要概念

容量(Capacity)泉唁,即HashMap中數(shù)組的大小鹅龄,也是桶的個(gè)數(shù)

負(fù)載因子(load factor),也成裝載因子 = hashmap中實(shí)際保存鍵值對(duì)個(gè)數(shù) / hashmap中數(shù)組的大小

隨著HashMap中元素個(gè)數(shù)的增多游两,負(fù)載因子增大砾层。如果不做額外的處理漩绵,則桶中的鏈表會(huì)越來(lái)越長(zhǎng)贱案,因此HashMap就無(wú)法保證取元素時(shí)O(1)的時(shí)間復(fù)雜度。因此止吐,必須要調(diào)整HashMap中數(shù)組的大小

HashMap中定義的默認(rèn)負(fù)載因子大小為0.75宝踪,當(dāng)負(fù)載因子大于該值時(shí),將對(duì)數(shù)組進(jìn)行擴(kuò)容

8. HashMap其他面試題

HashMap與HashTable區(qū)別:Hashtable中加入了鎖碍扔,線程安全瘩燥;HashMap線程不安全。也正因?yàn)镠ashtable中加入了鎖不同,導(dǎo)致性能上要差于HashMap厉膀。

ConcurrentHashMap:HashMap、Hashtable在性能和安全性上的一個(gè)折中方案二拐。實(shí)現(xiàn)原理是ConcurrentHashMap中將Map劃分為多個(gè)子Map服鹅,子Map分別加鎖。對(duì)一個(gè)子Map加鎖以后乡括,不影響對(duì)其他子Map的訪問(wèn)丘侠。

9. 為什么要面試這道題目

a. 考察求職者技術(shù)水平.

我一把把這道題目作為第一道面試題來(lái)考察求職者姑廉。根據(jù)回答情況,能大致推測(cè)到求職者的水平仗哨,方便后續(xù)的面試形庭。

零級(jí)水平:完全不知道。(當(dāng)然厌漂,這種可能性很少萨醒。畢竟HashMap是非常常用的一個(gè)工具類)

一級(jí)水平:可以回答HashMap的時(shí)間復(fù)雜度,容量桩卵,裝載因子等概念

二級(jí)水平:回答出get/put操作的完整過(guò)程验靡。(多數(shù)求職者都沒(méi)能完整的回答這個(gè)問(wèn)題。能完全回答出這個(gè)問(wèn)題雏节,說(shuō)明求職者對(duì)哈希的思想有完整的理解胜嗓,而且很可能閱讀過(guò)HashMap的源碼 - 要想寫好代碼,首先要閱讀優(yōu)秀源代碼的習(xí)慣)

三級(jí)水平:回答出hashCode钩乍,equals作用辞州,不可變性,線程安全的Map(基本上滿足公司實(shí)習(xí)生的要求寥粹,可以發(fā)offer了)

b. 考察求職者表達(dá)能力

能夠把一件復(fù)雜的事情講的清晰易懂变过,是件了不起的能力。(筆者在這方面能力有所欠佳)


注:

HashMap中其實(shí)允許null作為key涝涤,因?yàn)樵趃et/put操作時(shí)都會(huì)對(duì)null值做特殊的處理媚狰。

本文主要是從哈希表的角度來(lái)講述HashMap,因此這些細(xì)節(jié)問(wèn)題并未涉及阔拳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崭孤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子糊肠,更是在濱河造成了極大的恐慌辨宠,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件货裹,死亡現(xiàn)場(chǎng)離奇詭異嗤形,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)弧圆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門赋兵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人搔预,你說(shuō)我怎么就攤上這事霹期。” “怎么了斯撮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵经伙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)帕膜,這世上最難降的妖魔是什么枣氧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮垮刹,結(jié)果婚禮上达吞,老公的妹妹穿的比我還像新娘。我一直安慰自己荒典,他們只是感情好酪劫,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著寺董,像睡著了一般覆糟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上遮咖,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天滩字,我揣著相機(jī)與錄音,去河邊找鬼御吞。 笑死麦箍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的陶珠。 我是一名探鬼主播挟裂,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼揍诽!你這毒婦竟也來(lái)了诀蓉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寝姿,失蹤者是張志新(化名)和其女友劉穎交排,沒(méi)想到半個(gè)月后划滋,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體饵筑,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年处坪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了根资。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡同窘,死狀恐怖玄帕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情想邦,我是刑警寧澤裤纹,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響鹰椒,放射性物質(zhì)發(fā)生泄漏锡移。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一漆际、第九天 我趴在偏房一處隱蔽的房頂上張望淆珊。 院中可真熱鬧,春花似錦奸汇、人聲如沸施符。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)戳吝。三九已至,卻和暖如春贯涎,著一層夾襖步出監(jiān)牢的瞬間骨坑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工柬采, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欢唾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓粉捻,卻偏偏與公主長(zhǎng)得像礁遣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肩刃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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

  • 大部分Java開(kāi)發(fā)者都在使用Map祟霍,特別是HashMap。HashMap是一種簡(jiǎn)單但強(qiáng)大的方式去存儲(chǔ)和獲取數(shù)據(jù)盈包。但...
    騷的掉渣閱讀 789評(píng)論 0 14
  • 很多剛學(xué)Java的同學(xué)們都知道HashMap沸呐,平常一般使用,可能并不知道它的工作原理呢燥,前段時(shí)間有為剛畢業(yè)的同事在使...
    楊文杰閱讀 8,279評(píng)論 6 12
  • HashMap 是 Java 面試必考的知識(shí)點(diǎn)崭添,面試官?gòu)倪@個(gè)小知識(shí)點(diǎn)就可以了解我們對(duì) Java 基礎(chǔ)的掌握程度。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,661評(píng)論 9 107
  • 2017年8月31日晴 今天是烽熠的大日子叛氨,從今天起她就是一名小學(xué)生了呼渣,我倆都懷著激動(dòng)的心情早早就起床了,匆匆吃過(guò)...
    李烽熠媽閱讀 137評(píng)論 0 0
  • 禁止中學(xué)生早戀寞埠,被眾多學(xué)校列為禁令屁置,輕者勸勉談話,重者邀請(qǐng)家長(zhǎng)到校仁连,甚至給予勒令離校的處分蓝角。在很多家長(zhǎng)和老師看來(lái),...
    雪后山閱讀 673評(píng)論 6 7