亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原(yuan)創

HashMap如何處理沖突

2023-07-03 11:18:45
9
0

HashMap在處理沖(chong)突時,使用了(le)鏈(lian)(lian)表和紅黑(hei)樹的結構。當多個(ge)鍵(jian)值對被映射到同一(yi)個(ge)索引位置時,它們會(hui)被添加到鏈(lian)(lian)表或紅黑(hei)樹的尾部。這樣可以(yi)通過遍(bian)歷鏈(lian)(lian)表或紅黑(hei)樹來查找沖(chong)突的鍵(jian)值對。

以下是(shi)HashMap源碼中處理沖(chong)突(tu)的部分:

```java
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    // 如果哈希表為空,則進行初始化
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    // 計算哈希碼對應的索引位置
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
        // 如果鍵已存在,則直接替換對應的值
        if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        // 如果哈希沖突,且該節點存儲的是紅黑樹,將鍵值對添加到紅黑樹中
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        // 如果哈希沖突,且該節點存儲的是鏈表,在尾部添加新的節點
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    // 如果鏈表長度大于等于8,則將鏈表轉換為紅黑樹
                    if (binCount >= TREEIFY_THRESHOLD - 1)
                        treeifyBin(tab, hash);
                    break;
                }
                // 如果鍵已存在于鏈表中,則直接替換對應的值
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        // 如果鍵已存在,則替換原值為新值
        if (e != null) {
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            // 節點更新后的操作
            afterNodeAccess(e);
            return oldValue;
        }
    }
    // 插入后的操作
    ++modCount;
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}
```

在上述代碼中,如果發生哈希沖(chong)突,會根據節點類型(xing)進行(xing)不同的處理(li):

- 如果節點存儲的是紅黑樹,則調用紅黑樹節點的putTreeVal方法,將鍵值對添加到紅黑樹中。
- 如果節點存儲的是鏈表,則遍歷鏈表,直到找到相同的鍵值對或鏈表的末尾。如果找到相同的鍵值對,則替換對應的值;如果沒找到,則在鏈表尾部添加新的節點。
- 如果鏈(lian)表長度達到閾(yu)值,則將(jiang)鏈(lian)表轉換(huan)為紅(hong)黑(hei)樹,以提高(gao)查詢性能。

通過使用鏈表和(he)紅(hong)黑(hei)樹,HashMap可以(yi)實現高效(xiao)的查(cha)找(zhao)和(he)更新操作(zuo),盡可能(neng)減(jian)少沖突帶來的影響。

0條評論
作者已關閉評論
t****m
98文章數
1粉絲(si)數
t****m
98 文(wen)章 | 1 粉絲
t****m
98文章數
1粉絲數(shu)
t****m
98 文章(zhang) | 1 粉絲
原(yuan)創(chuang)

HashMap如何處理沖突

2023-07-03 11:18:45
9
0

HashMap在(zai)處理(li)沖(chong)突時(shi),使用了鏈表(biao)(biao)和紅(hong)黑樹(shu)的結構。當多個鍵值對(dui)被映射到同(tong)一個索(suo)引位置時(shi),它們會被添加到鏈表(biao)(biao)或紅(hong)黑樹(shu)的尾部。這(zhe)樣可以通過遍歷鏈表(biao)(biao)或紅(hong)黑樹(shu)來查找沖(chong)突的鍵值對(dui)。

以下是HashMap源碼(ma)中(zhong)處理沖突的(de)部分:

```java
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    // 如果哈希表為空,則進行初始化
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    // 計算哈希碼對應的索引位置
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
        // 如果鍵已存在,則直接替換對應的值
        if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        // 如果哈希沖突,且該節點存儲的是紅黑樹,將鍵值對添加到紅黑樹中
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        // 如果哈希沖突,且該節點存儲的是鏈表,在尾部添加新的節點
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    // 如果鏈表長度大于等于8,則將鏈表轉換為紅黑樹
                    if (binCount >= TREEIFY_THRESHOLD - 1)
                        treeifyBin(tab, hash);
                    break;
                }
                // 如果鍵已存在于鏈表中,則直接替換對應的值
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        // 如果鍵已存在,則替換原值為新值
        if (e != null) {
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            // 節點更新后的操作
            afterNodeAccess(e);
            return oldValue;
        }
    }
    // 插入后的操作
    ++modCount;
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}
```

在上述代(dai)碼中,如(ru)果發生哈(ha)希(xi)沖(chong)突,會根據節點類型(xing)進(jin)行不(bu)同的處理(li):

- 如果節點存儲的是紅黑樹,則調用紅黑樹節點的putTreeVal方法,將鍵值對添加到紅黑樹中。
- 如果節點存儲的是鏈表,則遍歷鏈表,直到找到相同的鍵值對或鏈表的末尾。如果找到相同的鍵值對,則替換對應的值;如果沒找到,則在鏈表尾部添加新的節點。
- 如果鏈表長度達到閾值,則將鏈表轉換(huan)為紅黑樹,以提高查詢(xun)性能(neng)。

通過使用(yong)鏈(lian)表和紅黑樹,HashMap可以實現高效的查(cha)找和更新操作,盡可能減少沖突帶來的影響(xiang)。

文章來自個人專欄
文章 | 訂(ding)閱
0條評論
作者已關閉評論
作者已關閉評論
0
0