日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试必备:HashMap底层数据结构?jdk1.8算法优化,hash冲突,扩容等问题

發(fā)布時間:2023/12/10 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试必备:HashMap底层数据结构?jdk1.8算法优化,hash冲突,扩容等问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

面試必備系列不會長篇理論求證,直接上答案,僅供參考,不喜勿噴。

1、能說說HashMap的底層原理嗎?

HashMap<String,String>?map?=?new?HashMap<String,String>();?

map.put(“key”,”value”);?

[<key1,value1>,<key2,value2>,<key3,value3>]?

HashMap底層實現(xiàn)是數(shù)組+鏈表,用來存儲<key,value>形式的數(shù)據(jù),當我們調(diào)用put(key,value)時,首先會通過hash(key) 來獲取key的hash值,hash值對數(shù)組長度進行取模運算,定位到數(shù)組的一個存儲位置 bucket,如果bucket沒有發(fā)生沖突的話則直接放入數(shù)組,發(fā)生沖突的話則以鏈表的形式存儲,jdk1.8之后引入了紅黑樹,鏈表的長度超過8之后會使用紅黑樹,小于6之后則又轉(zhuǎn)換回來。

如下2、3條皆為第1條的補充,預(yù)防面試官細問。

2、jdk1.8中對hash算法和尋址算法的優(yōu)化

jdk1.8中對hash算法進行了優(yōu)化,之前在對key進行hash(key)計算時,采用的是取模運算,即第1條提到的,而優(yōu)化后采用的是尋址算法,即:(n-1) & hash 『n為數(shù)組長度』

為什么要使用尋址算法呢?首先 「hash & (n-1)」 效果跟 hash 對 n 取模的效果是一樣的, 但是『&』與運算的性能要優(yōu)于 hash 對 n 取模。

3、hash沖突?怎么解決?

當我們put<key,value>時,首先通過hash(key)計算得到的hash值,再通過『&』與運算之后,得到了數(shù)組存儲位置bucket,但此時出現(xiàn)了兩個不同的key卻計算出相等的bucket,舉個例子:

數(shù)組A[0]位置計算出存放<張三,我是張三>數(shù)據(jù),而在put<李四,我是李四>數(shù)據(jù)時,也計算為存放在A[0]位置,一個位置想存放兩個數(shù)據(jù)?這就出現(xiàn)hash沖突了,怎么處理呢?

JDK是這樣處理的,它會在這個位置(A[0])掛一個鏈表,這個鏈表表里面存放出現(xiàn)沖突的數(shù)據(jù),即:讓多個<key,value>數(shù)據(jù)同時放在數(shù)組的一個位置里。

get(key)時怎么取呢?當我們調(diào)用get(key)定位到數(shù)組位置時,如果發(fā)現(xiàn)這個位置掛載的是一個鏈表,那么就遍歷鏈表,從里面找到自己想要的那個<key,value>數(shù)據(jù)。

格外補充:這個地方,在JDK1.8之后引入了紅黑樹的概念,首先我們看一下為啥要引入紅黑樹,如果沒有引入紅黑樹,當數(shù)組掛載的鏈表達到一定長度之后,查詢是非常耗時的,性能比較差,時間復(fù)雜度為:O(n)「讀作:偶en」。

JDK1.8的優(yōu)化就是,當鏈表的長度發(fā)到了一定長度后(8)會自動轉(zhuǎn)換為紅黑樹,遍歷一棵紅黑樹查找一個元素的時間復(fù)雜度為:O(logn)「讀作:偶,老個en」,性能相對鏈表要高一些。

簡單總結(jié)一下:

  • 出現(xiàn)hash沖突的原因?兩個不同的key計算出相同的數(shù)組存放位置;

  • 初期是怎么解決的?在出現(xiàn)數(shù)組沖突的位置掛一個鏈表,實現(xiàn)存放多個數(shù)據(jù)。

  • JDK1.8的優(yōu)化?當數(shù)組長度達到一定值后自動轉(zhuǎn)換為紅黑樹,降低時間復(fù)雜度。

  • 4、HashMap是如何擴容的?

    HashMap底層是一個數(shù)組,當數(shù)組滿了之后,他會自動進行2倍擴容,用于盛放更多的數(shù)據(jù)。

    比如,本來數(shù)組默認長度=16,擴容后*2=32。

    擴容后還有一步操作:rehash,重新對每個hash值進行尋址,也就是用每個hash值跟新的數(shù)組長度 n-1 進行『&』與運算操作。

    補充:擴容之后的與運算可能會導(dǎo)致之前的發(fā)生hash沖突的元素不再發(fā)生沖突。

    博客地址:https://www.cnblogs.com/niceyoo

    總結(jié)

    以上是生活随笔為你收集整理的面试必备:HashMap底层数据结构?jdk1.8算法优化,hash冲突,扩容等问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。