HashMap的put方法實現機制

一、HashMap簡介

HashMap是一個常用的數據結構,它實現了一個鍵值對映射的哈希表。它通過將鍵映射到bucket中,來實現快速的查找。HashMap中每個bucket會保存一個entry鏈表或是紅黑樹,如果鏈表的長度超過了一個預定的閥值,就會將鏈錶轉換為紅黑樹,這樣可以提高查找的效率。

二、HashMap的put方法實現

HashMap的put方法實現比較複雜,它會涉及到哈希值計算、尋找桶、查找以及對桶進行操作等操作。

1. 哈希值計算

在插入元素時,HashMap會根據元素的key來計算它的哈希值。這個哈希值是一個int類型的值,它的作用是用來確定該元素的桶位置。將哈希值對桶數組的長度取模,得到的餘數就是該元素所在桶的位置。具體的計算方式為:

/**
 * 計算key的哈希值
 */
final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

其中,key.hashCode()計算出的哈希值可能會產生衝突,為了減少衝突,Java使用了一種演算法將key.hashCode()的高16位與低16位進行異或運算,得到一個更加均勻分布的哈希值。

2. 尋找桶

在得到元素的哈希值後,需要根據哈希值來找到對應的桶,這個過程叫做尋找桶。HashMap使用一個數組來存儲桶,使用哈希值對數組長度取模可以得到對應的桶的位置。

/**
 * 根據哈希值獲取桶的位置
 */
final Node getNode(int hash, Object key) {
    Node[] tab; 
    Node first, e; 
    int n; 
    K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        // ...
    }
    return null;
}

在這段代碼中,tab表示桶數組,如果桶數組不為空,那麼根據桶數組的長度和元素的哈希值得到的下標找到對應的桶first。該桶first是一個單向鏈表的頭節點,如果first不為空,就遍歷該鏈表,找到對應的元素。

3. 查找

在找到元素所在的桶後,需要在桶中查找該元素。由於HashMap中每個桶會存儲一個entry鏈表或是紅黑樹,所以需要根據鏈表或紅黑樹的數據結構不同,採用不同的方式進行查找。

對於entry鏈表,查找方式為遍歷鏈表。遍歷鏈表的過程是一個while循環,不斷將當前節點更新為下一個節點,直到找到對應的元素為止。

/**
 * 在桶中查找元素
 */
for (e = first; e != null; e = e.next) {
    if ((e.hash == hash) && ((k = e.key) == key || (key != null && key.equals(k)))) {
        oldValue = e.value;
        if (!onlyIfAbsent || oldValue == null)
            e.value = value;
        afterNodeAccess(e);
        return oldValue;
    }
}

對於紅黑樹,查找方式為紅黑樹的查找方式。紅黑樹是一種自平衡的二叉查找樹,它的查找操作的時間複雜度是O(log n)。

/**
 * 在紅黑樹中查找元素
 */
else if (p instanceof TreeNode)
    oldValue = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);

4. 對桶進行操作

在完成查找操作後,就可以根據查找的結果對桶進行相關操作。主要分為以下兩種情況:

1)在桶中未找到對應元素,需要將元素添加到桶中。

/**
 * 向桶中插入元素
 */
void addEntry(int hash, K key, V value, int bucketIndex) {
    // ...
    createEntry(hash, key, value, bucketIndex);
    if (size++ >= threshold)
        resize(2 * table.length);
    afterNodeInsertion(true);
}

在插入元素時,如果桶中未找到對應元素,那麼就需要將該元素添加到桶中。這時需要將元素插入到鏈表或紅黑樹的末尾。如果插入後鏈表長度超過了一定長度,就需要將鏈錶轉換為紅黑樹,以提高查找效率。除此之外,如果插入元素後HashMap的容量已經達到閥值,那麼就需要對桶數組進行擴容,以便存放更多的元素。

2)在桶中找到對應元素,需要更新該元素的值。

/**
 * 更新桶中的元素
 */
if (e != null) { 
    V oldValue = e.value;
    if (!onlyIfAbsent || oldValue == null)
        e.value = value;
    afterNodeAccess(e);
    return oldValue;
}

更新桶中元素的過程比較簡單,只需要將新的值賦給該元素即可。

三、總結

HashMap是一個重要的數據結構,在Java開發中被廣泛使用。它的put方法實現機制比較複雜,需要涉及到哈希值計算、尋找桶、查找以及對桶進行操作等多個步驟。掌握HashMap的put方法實現機制能夠幫助我們更好地理解和使用HashMap。

原創文章,作者:AHEXD,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/325432.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
AHEXD的頭像AHEXD
上一篇 2025-01-13 13:24
下一篇 2025-01-13 13:24

相關推薦

  • 解決.net 6.0運行閃退的方法

    如果你正在使用.net 6.0開發應用程序,可能會遇到程序閃退的情況。這篇文章將從多個方面為你解決這個問題。 一、代碼問題 代碼問題是導致.net 6.0程序閃退的主要原因之一。首…

    編程 2025-04-29
  • ArcGIS更改標註位置為中心的方法

    本篇文章將從多個方面詳細闡述如何在ArcGIS中更改標註位置為中心。讓我們一步步來看。 一、禁止標註智能調整 在ArcMap中設置標註智能調整可以自動將標註位置調整到最佳顯示位置。…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • Python創建分配內存的方法

    在python中,我們常常需要創建並分配內存來存儲數據。不同的類型和數據結構可能需要不同的方法來分配內存。本文將從多個方面介紹Python創建分配內存的方法,包括列表、元組、字典、…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • 用不同的方法求素數

    素數是指只能被1和自身整除的正整數,如2、3、5、7、11、13等。素數在密碼學、計算機科學、數學、物理等領域都有著廣泛的應用。本文將介紹幾種常見的求素數的方法,包括暴力枚舉法、埃…

    編程 2025-04-29
  • 使用Vue實現前端AES加密並輸出為十六進位的方法

    在前端開發中,數據傳輸的安全性問題十分重要,其中一種保護數據安全的方式是加密。本文將會介紹如何使用Vue框架實現前端AES加密並將加密結果輸出為十六進位。 一、AES加密介紹 AE…

    編程 2025-04-29
  • Python學習筆記:去除字元串最後一個字元的方法

    本文將從多個方面詳細闡述如何通過Python去除字元串最後一個字元,包括使用切片、pop()、刪除、替換等方法來實現。 一、字元串切片 在Python中,可以通過字元串切片的方式來…

    編程 2025-04-29
  • 用法介紹Python集合update方法

    Python集合(set)update()方法是Python的一種集合操作方法,用於將多個集合合併為一個集合。本篇文章將從以下幾個方面進行詳細闡述: 一、參數的含義和用法 Pyth…

    編程 2025-04-29
  • Vb運行程序的三種方法

    VB是一種非常實用的編程工具,它可以被用於開發各種不同的應用程序,從簡單的計算器到更複雜的商業軟體。在VB中,有許多不同的方法可以運行程序,包括編譯器、發布程序以及命令行。在本文中…

    編程 2025-04-29

發表回復

登錄後才能評論