存储在同一个桶中的元素在重新散列后是否可以重新分配到不同的桶中?

Could elements stored in the same bucket be reassigned to separate buckets after rehashing?

到现在为止,我知道在 HashMap 中重新散列后,所有条目都使用新的 table 长度重新散列。但是我想知道当我发生碰撞时会发生什么。

例如

Map<String, String> map = new HashMap<>(5); 
map.put("a", "ape");
map.put("b", "bird"); 
map.put("c", "chicken");

假设他们有不同的哈希码,但是"b""c"经过内部哈希后存储在同一个桶中。

现在我将插入第四个条目以达到负载因子,因此重新散列 table:

map.put("d", "dynamite");

是否可以将有冲突的条目存储在单独的存储桶中,或者它们将始终在一起(根据我阅读的内容以相反的顺序)?

我想标题的答案是否定的,因为我会为 "b""c" 获得相同的内部散列,但我不确定。

根据表达式 hashcode % capacity 表示的数字是否保持不变 post 重新散列,它们可以存储在同一个桶或不同的桶中.

例如假设字符串对象 "b" 和 "c" 返回的哈希码是 27 和 32。您的初始容量是 5。所以表达式 hashcode % capacity 等于 2 "a" 和 "b" 均为 2。因此它们都将存储在同一个桶中。现在在重新散列之后(当散列中的条目数 table 超过负载因子和当前容量的乘积时),新容量大约翻倍。假设新容量为 10。因此表达式 hashcode % capacity 现在将分别等于 7 和 2。这意味着这 2 个对象现在将存储在单独的桶中 post 重新散列。

现在考虑以下情况。比如说,这 2 个对象返回的 hashCodes 是 27 和 37。在这种情况下,表达式 hashcode % capacity 在哈希之前等于 2 和 2,在哈希之后等于 7 和 7。所以它们仍然会存储在同一个桶中。

您可以通过两种方式在此处查看碰撞。

一个是两个 objects return 从 hashCode() 方法中获取相同的值。在这种情况下,无论哈希表数组的大小如何,它们最终都会在同一个桶中。

另一种情况是两个 object 具有不同的哈希码,但由于数组大小小于 232 唯一性而最终位于同一个桶中hashCode() 理论上可以 return 的值。通常,原始哈希码值将取模数组大小,用于为条目找到正确的桶。假设初始数组大小为 16,并且您有 object A,哈希码为 3,object B,哈希码为 19。由于 19 % 16 == 3,object A 和 object B 将最终进入同一个桶。如果现在将数组的大小调整为 18,object A 将在桶 3 % 20 == 3 中结束,但 object B 将在桶 19 % 20 == 19 中结束。所以现在他们在用 "yes".

回答标题中提出的问题的不同桶