hashMap的底層實現

2022-05-01 12:42:09 字數 1567 閱讀 7734

陣列:儲存區間連續,占用記憶體嚴重,定址容易,插入刪除困難

鍊錶:儲存區間離散,占用記憶體比較寬鬆,定址困難,插入刪除容易

hashmap綜合應用了這兩種資料結構,實現了定址容易,插入刪除也容易

hashmap結構示意圖:

實現原理:用乙個陣列來儲存元素,但是這個陣列儲存的不是基本資料型別。hashmap實現巧妙的地方就在這裡,陣列儲存的元素是乙個entry類,這個類有三個資料域,key、value(鍵值對),next(指向下乙個entry)

那hashmap是怎麼確定插入乙個值的時候怎麼確定該把這個元素插入這個陣列的哪個位置呢?

實際上是通過這個演算法實現的:key.hashcode()%array.length    位置下標由key的雜湊值對陣列的長度取模得到,如果兩個輸入串的hash函式的值一樣,則稱這兩個串是乙個碰撞(collision),也就是雜湊碰撞,當新插入資料時,hashmap會先用key的hash值檢查table 位置, 如果這個位置沒有值就放入(沒有雜湊碰撞),如果有值,就用equals() 分別比較key 如果相等就替換該value 值。如果不等就放在鍊錶的首位並next指標指向下乙個entry

hashcode是jdk根據物件的位址或者字串或者數字算出來的int型別的數值 ,public int hashcode()返回該物件的雜湊碼值

說到這裡,又有乙個問題了,如果兩個key經過計算後得到相同的陣列下標怎麼辦?

這裡用到的就是乙個鍊錶,hashmap在插入元素的時候,會首先檢查這個位置上有沒有元素,如果已經有了元素,那麼就把這個新插入的entry的next指向本來這個位置上的元素的位址,然後再插入這個位置,這也就是為什麼插入多個相同的key的value時,這個位置的value始終是最後插入的那個元素的值。

兩者之間唯一的必然關係被你說反了,equls返回為true,則兩者的hashcode一定相等,意即相等的物件必須具有相等的雜湊碼。每當equals方法被覆寫,通常需要重寫hashcode方法從而

保持物件行為的一致性。而具有相等的hashcode的兩個物件equals不一定成立。你可以這樣認為也行,hashcode是作為乙個物件儲存的參考,hash表本身是一種雜湊表,在資料儲存這塊,功效比較大,而equals是相當於兩物件之間的屬性(成員變數)「相等」,意即具有相同的行為(方法)。或許這樣講起來理解比較的費勁。舉個例子,比如你定義class a有兩個屬性,int aa,ab,在定義乙個class b也有兩個屬性,int ba,bb,然後覆寫hashcode方法,a類為return aa*ab;b類為return ba*bb.現在情況已經很顯然了,各自例項化乙個物件:a,b,假如:a.aa=b.ba,a.ab=b.bb,相等,或者a.aa=b.bb,a.ab=b.ba兩個物件a,b的hashcode一定相等,當時你能說兩個物件相等嗎?顯然不能吧,a與b都是不同類的例項。連equals最基本的obj instance of a或是obj instance of b都不成立。如果是同乙個類的不同物件,擁有相同hashcode的時候,則一定相等,或者equals成立的時候則hashcode一定為真,這也就是所謂的相等

的物件具有行為一致性。

HashMap底層實現

hashmap中定義了乙個node結構,很明顯可以看出這是乙個鍊錶的節點定義。鍵值對key和value以及key的hash值都儲存在這個節點中 static class node implements map.entry hashmap的插入方法在key值已存在的時候是直接替換掉value值,若ke...

HashMap的底層實現

hashmap底層是使用陣列和鍊錶結合在一起使用,即鍊錶雜湊。hashmap通過key的hashcode經過擾動函式hash int h 處理後得到hash值,然後通過 n 1 hash 確定該元素存放的位置,if 當前位置已存在元素,就判斷當前位置的元素hash值以及key 是否相同,如果相同則直...

hashmap底層實現原理

每次初始化hashmap都會構造乙個table陣列,而table陣列的元素為entry節點。static class entryimplements map.entryhashmap也可以說是乙個陣列鍊錶,hashmap裡面有乙個非常重要的內部靜態類 entry,這個entry非常重要,它裡面包含了...