HashMap如何在Java內部工作

在本文中,我們將看到HashMap如何在Java內部工作。此外,我們還將瞭解Java 8對Hashmap的內部工作進行了哪些更改,以使其更快。

A HashMap用於存儲鍵值對映射的映射。要了解關於HashMap的更多信息,請訪問本文:Java中的HashMap

Java中的HashMap工作在散列原則上。它是一種數據結構,允許我們存儲對象並在恆定時間內檢索對象O(1),前提是我們知道密鑰。在散列中,哈希函數用於鏈接HashMap中的鍵和值。

Hashmap如何用Java計算桶的索引

要了解HashMap如何在Java內部工作,我們必須瞭解HashMap是如何計算桶的索引的。到目前爲止,我們知道HashMap的內部結構,HashMap維護一個桶數組。但是,當我們存儲或檢索任何鍵值對時,HashMap會爲每個操作計算桶的索引。關鍵對象用於計算桶的索引。通過使用此鍵,將使用hash(key)HashMap的私有方法。

注: hash(key)方法是HashMap的一個私有方法,它返回鍵的哈希值,如果哈希值太大,則將其轉換爲較小的哈希值。

但會發生什麼如果鍵對象的散列值返回大於數組大小的整數,即,散列(鍵)>n,然後ArrayOutOfBoundsException可以被提升。爲了處理這種情況,HashMap使用一個表達式減少了0到n-1之間的哈希值:

索引計算表達式:

index = hash(key) & (n-1)

現在,此索引值是由HashMap生成的,用於查找桶位置,並且永遠不能生成任何異常,因爲索引值總是從0到n-1。

put()方法做什麼

讓我們記錄一下hashmap中put方法的內部工作。

首先,檢查鍵對象是否爲NULL。

如果鍵爲空,則將值存儲在 table[0]位置,因爲空的哈希代碼總是0。

然後在下一步中,使用密鑰的哈希代碼通過調用hashCode() 方法。此哈希值用於計算數組中用於存儲條目對象的索引。jdk設計人員很好地假設可能有一些寫得不好的東西。hashCode()可以返回非常高或低哈希代碼值的函數。爲了解決這個問題,他們引入了另一個hash()函數,並將對象的哈希代碼傳遞給此散列()函數,以在數組索引大小的範圍內帶來哈希值。

現在indexFor(hash, table.length)函數來計算用於存儲條目對象的準確索引位置。

如何解決碰撞

主要部分來了。現在,正如我們所知道的,兩個不相等的對象可以具有相同的哈希代碼值,那麼如何將兩個不同的對象存儲在一個稱爲桶的數組位置。

答案是LinkedList。如果您還記得,Entry類有一個屬性“next“這個屬性總是指向鏈中的下一個對象,這正是LinkedList的行爲。

因此,在發生衝突時,條目對象存儲在鏈表形式中。當條目對象需要存儲在特定索引中時,HashMap將檢查條目是否已經存在。如果沒有已出現的條目,則將條目對象存儲在此位置。

如果計算的索引上已經有一個對象,則將檢查它的下一個屬性。如果爲NULL,則當前條目對象將成爲LinkedList中的下一個節點。如果下一個變量爲NOTNULL,則遵循該過程,直到下一個變量被計算爲NULL爲止。

如果我們用與前面輸入的鍵相同的鍵添加另一個值對象,該怎麼辦?從邏輯上講,它應該取代舊的值。怎麼做的?在確定了條目對象的索引位置之後,在計算的索引上迭代LinkedListd時,HashMap對每個條目對象的鍵對象調用等於方法。

LinkedList中的所有這些條目對象都有類似的哈希代碼,但是equals() 方法將測試是否真正相等。如果key.equals(k)則這兩個鍵將被視爲相同的鍵對象。這隻會導致只替換條目對象中的值對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章