哈希表由數(shù)組+鏈表組成。 HashMap存儲的是一個線性數(shù)組,里面實現(xiàn)了一個靜態(tài)內(nèi)部類Entry,有key, value, next這些屬性。
put get null key index = hashcode % table.code
解決hash沖突的辦法:鏈地址法 再散列rehash過程
什么時候會使用HashMap?HashMap有什么特點?
是基于Map接口的實現(xiàn),存儲鍵值對時,它可以接收null的鍵值,是非同步的,HashMap存儲著Entry(hash, key, value, next)對象。
你知道HashMap的工作原理嗎?
通過hash的方法,通過put和get存儲和獲取對象。存儲對象時,我們將K/V傳給put方法時,它調(diào)用hashCode計算hash從而得到bucket位置,進一步存儲,HashMap會根據(jù)當(dāng)前bucket的占用情況自動調(diào)整容量(超過Load Facotr則resize為原來的2倍)。獲取對象時,我們將K傳給get,它調(diào)用hashCode計算hash從而得到bucket位置,并進一步調(diào)用equals()方法確定鍵值對。如果發(fā)生碰撞的時候,Hashmap通過鏈表將產(chǎn)生碰撞沖突的元素組織起來,在java 8中,如果一個bucket中碰撞沖突的元素超過某個限制(默認(rèn)是8),則使用紅黑樹來替換鏈表,從而提高速度。
你知道get和put的原理嗎?equals()和hashCode()的都有什么作用?
通過對key的hashCode()進行hashing,并計算下標(biāo)( n-1 & hash),從而獲得buckets的位置。如果產(chǎn)生碰撞,則利用key.equals()方法去鏈表或樹中去查找對應(yīng)的節(jié)點
你知道hash的實現(xiàn)嗎?為什么要這樣實現(xiàn)?
在Java 1.8的實現(xiàn)中,是通過hashCode()的高16位異或低16位實現(xiàn)的:(h = k.hashCode()) ^ (h >>> 16),主要是從速度、功效、質(zhì)量來考慮的,這么做可以在bucket的n比較小的時候,也能保證考慮到高低bit都參與到hash的計算中,同時不會有太大的開銷。
如果HashMap的大小超過了負載因子(load factor)定義的容量,怎么辦?
如果超過了負載因子(默認(rèn)0.75),則會重新resize一個原來長度兩倍的HashMap,并且重新調(diào)用hash方法。
新聞熱點
疑難解答