Java 达到最大链长度时调整哈希表的大小

Java 达到最大链长度时调整哈希表的大小,java,algorithm,hashtable,Java,Algorithm,Hashtable,我正在实现一个用于教育目的的哈希表。哈希表用数组实现,冲突用链表处理。说明书上说,我可以插入相同的项目,而无需检查以提高插入速度。但当链长度达到允许的最大值时,需要调整哈希表的大小。但我发现调整大小根本没有帮助,因为即使数组长度增加,相同的项目仍然会进入相同的存储桶。我错过什么了吗?多谢各位 让我们举个例子:三个hashcode为7、23和47的对象 如果哈希表的大小为8,那么通过模运算,所有这些对象都将进入哈希桶7 另一方面,如果哈希表的大小为16,则前两个将进入哈希桶7,而另一个将进入哈希桶

我正在实现一个用于教育目的的哈希表。哈希表用数组实现,冲突用链表处理。说明书上说,我可以插入相同的项目,而无需检查以提高插入速度。但当链长度达到允许的最大值时,需要调整哈希表的大小。但我发现调整大小根本没有帮助,因为即使数组长度增加,相同的项目仍然会进入相同的存储桶。我错过什么了吗?多谢各位

让我们举个例子:三个hashcode为7、23和47的对象

如果哈希表的大小为8,那么通过模运算,所有这些对象都将进入哈希桶7

另一方面,如果哈希表的大小为16,则前两个将进入哈希桶7,而另一个将进入哈希桶15

说明书上说,我可以插入相同的项目,而无需检查以提高插入速度

您不能完全跳过检查,因为最终会在同一个链上出现重复项

但我发现调整大小根本没有帮助,因为即使数组长度增加,相同的项目仍然会进入相同的存储桶

这只会发生在哈希值低于表大小的情况下。对于表大小以上的值,
%
运算符通常会将项目放在不同的存储桶中,前提是您避免了别名问题


为了避免混淆,请使用与素数对应的表大小。有关这方面的更多信息,请参阅。

我可以告诉您jdk是如何处理的。您的条目(键)覆盖hashcode,它是一个int(由32位组成)。当您有16个bucket(内部数组的长度为16)时,在内部执行的用于查找条目的位置的操作是:

 hash_code & (array.lenght - 1) // this is the same as modulo operation
                                // if array.lenght is power of two.
这意味着,当您将条目放入映射时,只考虑条目哈希代码的最后4位

现在,当您填充这16个条目时(其中一个实现了负载因子):内部数组变大了(让我们将其加倍),因此现在它有32个条目

这意味着将计算确定条目的位置:

   hash_code & (32 - 1) // now there are 5 bits take into consideration

您的所有条目现在都被重新散列(因为现在还有一位),您的条目这次可能会在不同的存储桶中结束

如果您有一个哈希表,那么计算输入哈希的正确bucket索引的算法应该根据bucket的数量(您的数组长度)计算索引。您可能会发现它很有用-更好的是,如果大小为15,则所有3个都会转到不同的bucket技术上正确。但是大多数hashmaps的bucket长度都是2的幂,因为它们可以利用
&
操作符,使映射更具性能。谢谢大家的评论。但我认为bucket长度总是素数(?),你可能在考虑散列码的计算,它通常会涉及素数,以提高均匀分布的机会。但是桶的数量将是2的幂。