簡體   English   中英

為什么HashMap在索引(n-1)和哈希上插入新的Node?

[英]Why HashMap insert new Node on index (n - 1) & hash?

為什么HashMap在索引上插入新節點: tab[(n - 1) & hash]

其中hash = key.hashCode() ^ key.hashCode() >>> 16n = tab.lengthNode<K,V>數組。

為什么HashMap沒有像這樣放置Node: tab[hash] 它只是另一個散列函數,比如在大多數hashCode()方法中乘以31嗎? 在此先感謝您的解釋!

因為hash可能超出范圍。

“規范解決方案”是使用數組長度獲取散列的(正)模數,此代碼使用數組具有2的冪長度來替換昂貴的模數的事實(模數為a使用廉價的按位AND,可以很好地優化常量。

哈羅德的一個很好的描述,但我覺得沒有一個例子是不夠的。 所以繼承人 -

每當創建一個新的Hasmap時,內部Node []表的數組大小總是2的冪,並且以下方法保證 -

static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

所以假設您提供的初始容量為5

cap = 5
n = cap - 1 =  4 = 0 1 0 0
n |= n >>> 1;    0 1 0 0 | 0 0 1 0 = 0 1 1 0 = 6
n |= n >>> 2;    0 0 1 1 | 0 1 1 0 = 0 1 1 1 = 7
n |= n >>> 4;    0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
n |= n >>> 8;    0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
n |= n >>> 16;   0 0 0 0 | 0 1 1 1 = 0 1 1 1 = 7
return n + 1     7 + 1 = 8 

所以表大小是8 = 2 ^ 3

現在可以將元素放在map中的索引值為0-7,因為表大小為8.現在讓我們看一下put方法。 它查找桶索引如下 -

Node<K,V> p =  tab[i = (n - 1) & hash];

其中n是數組大小。 所以n = 8.就像說的一樣

Node<K,V> p =  tab[i = hash % n];

所以我們現在需要看到的是如何

hash % n == (n - 1) & hash

讓我們再舉一個例子。 讓我們說一個值的哈希是10。

hash = 10
hash % n = 10 % 8 = 2
(n - 1) & hash = 7 & 10 = 0 1 1 1 & 1 0 1 0 = 0 0 1 0 = 2

希望這可以幫助。 更多細節

PS:以上鏈接轉到我的博客,其中有更詳細的示例解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM