[英]Why HashMap insert new Node on index (n - 1) & hash?
為什么HashMap在索引上插入新節點: tab[(n - 1) & hash]
其中hash = key.hashCode() ^ key.hashCode() >>> 16
和n = tab.length
的Node<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.