1. 程式人生 > >hashMap的底層實現

hashMap的底層實現

但是 重寫 位置 LG mar sele earch hash表 equal

HashMap實現原理,利用數組和鏈表存儲元素

數組:存儲區間連續,占用內存嚴重,尋址容易,插入刪除困難

鏈表:存儲區間離散,占用內存比較寬松,尋址困難,插入刪除容易

hashmap綜合應用了這兩種數據結構,實現了尋址容易,插入刪除也容易

HashMap結構示意圖:

技術分享圖片技術分享圖片技術分享圖片

實現原理:用一個數組來存儲元素,但是這個數組存儲的不是基本數據類型。HashMap實現巧妙的地方就在這裏,數組存儲的元素是一個Entry類,這個類有三個數據域,key、value(鍵值對),next(指向下一個Entry)

那HashMap是怎麽確定插入一個值的時候怎麽確定該把這個元素插入這個數組的哪個位置呢?

實際上是通過這個算法實現的:key.hashCode()%Array[].length 位置下標由key的哈希值對數組的長度取模得到

hashCode是jdk根據對象的地址或者字符串或者數字算出來的int類型的數值 ,public int hashCode()返回該對象的哈希碼值

說到這裏,又有一個問題了,如果兩個key經過計算後得到相同的數組下標怎麽辦?

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

hash值相等,equals一定相等嗎,equals相等,hash值一定相等嗎

兩者之間唯一的必然關系被你說反了,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的底層實現