哈罗德的描述很好,但我觉得没有例子就不够了。所以这是一个 -
每当创建一个新的 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
希望这会有所帮助。 More details
PS:上面的链接转到我的博客,其中有更详细的示例说明。