Java Hashtable 如何根据 hashcode 计算元素的放置位置? [复制]
Posted
技术标签:
【中文标题】Java Hashtable 如何根据 hashcode 计算元素的放置位置? [复制]【英文标题】:How does Java Hashtable calculate where to place an element based on hashcode? [duplicate] 【发布时间】:2021-02-27 13:12:13 【问题描述】:在 Java 中,Hashtable 具有数量等于其容量的桶。现在它如何确定必须将对象存储在特定存储桶中?我知道它使用对象的哈希码,但哈希码是一个奇怪的长字符串,哈希表对哈希码做了什么来确定入口的位置?
【问题讨论】:
but hashcode is a weird long string
- 没有。 hashCode()
返回一个 int
。
一个散列码可以是任何东西,但在Java中散列码只是一个int
。
你看过HashTable
的源码吗?
【参考方案1】:
我知道它使用对象的哈希码,但哈希码是一个奇怪的长字符串,哈希表对哈希码做了什么来确定入口的位置?
哈希码不是“奇怪的长字符串”。它是一个 32 位有符号整数。
(我认为您混淆了哈希码以及调用 Object::toString
时得到的内容......这是一个由哈希码和 Java 内部类型名称组成的字符串。)
那么HashMap
和HashTable
(以及HashSet
和LinkedHashMap
)实际上做了什么:
hashCode()
获取32位整数,
对整数执行一些特定于实现的修改1,
通过删除符号位将错位整数转换为非负整数,
计算数组索引(对于存储桶)为value % array.length
,其中array
是哈希表的当前哈希链(或树)数组。
1 - HashMap
/ HashTable
的一些实现执行一些简单/廉价的按位修改。目的是在hashcode值的低几位分布不均匀的情况下减少聚类。
【讨论】:
【参考方案2】:依赖于实现(例如,如果你依赖它以这种方式工作,你的代码就会被破坏;HashMap 保证的东西在它的 javadoc 中有详细说明,而我要输入的内容都没有在那里):
哈希只是一个数字。大约在-20亿到+20亿之间。你看到的那个“长长的奇怪的字符串”只是向你展示它的一种更方便的方式。
首先,该数字的高位与低位混合(实际上,高位与低位进行异或):12340005 变成 12341239。
然后,这个数字除以当前有多少桶,但结果被扔掉了,这是我们感兴趣的余数。这个余数必须是 0 或更高,并且永远不会超过 '# of buckets there are ',所以总是准确地指向其中一个桶。
这是对象进入的桶。
如果存储桶变得太大,则调整大小。
更多信息,HashMap 和 HashSet 都是开源的 - 看看吧。
【讨论】:
Wilfred 可能不是故意的,但问题是关于HashTable 而不是HashMap。 这正是我所需要的。非常感谢,我只是想知道这一点。【参考方案3】:关于 jdk7 的行为,请参阅:
https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/Hashtable.java#L358
int index = (hash & 0x7FFFFFFF) % tab.length;
这是哈希表的常用技术。第一位被丢弃(使值变为正)。索引是按表大小划分的remainder。
【讨论】:
以上是关于Java Hashtable 如何根据 hashcode 计算元素的放置位置? [复制]的主要内容,如果未能解决你的问题,请参考以下文章