【问题标题】:How does Java Hashtable calculate where to place an element based on hashcode? [duplicate]Java Hashtable 如何根据 hashcode 计算元素的放置位置? [复制]
【发布时间】:2021-02-27 13:12:13
【问题描述】:

在 Java 中,Hashtable 具有数量等于其容量的桶。现在它如何确定必须将对象存储在特定存储桶中?我知道它使用对象的哈希码,但哈希码是一个奇怪的长字符串,哈希表对哈希码做了什么来确定入口的位置?

【问题讨论】:

  • but hashcode is a weird long string - 没有。 hashCode() 返回一个 int
  • 一个散列码可以是任何东西,但在Java中散列码只是一个int
  • 你看过HashTable的源码吗?

标签: java hash hashtable hashcode


【解决方案1】:

我知道它使用对象的哈希码,但哈希码是一个奇怪的长字符串,哈希表对哈希码做了什么来确定入口的位置?

哈希码不是“奇怪的长字符串”。它是一个 32 位有符号整数。

(我认为您混淆了哈希码以及调用 Object::toString 时得到的内容......这是一个由哈希码和 Java 内部类型名称组成的字符串。)

那么HashMapHashTable(以及HashSetLinkedHashMap)实际上做了什么:

  • 调用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

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 1970-01-01
      • 2022-07-06
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多