有没有办法从像HashMap这样的对象中获取Java的唯一哈希码?

时间:2011-11-07 07:24:22

标签: java hashmap hash

我相信如果我声明一个HashMap并重复提供它的Map.Entry实例,最终哈希码将与另一个哈希码冲突,即使这两个键(碰巧是我的需要的字符串)是不同的。

此时,HashMap和其他使用散列的类将生成一个不同的哈希码,作为内部使用的真正密钥。 (编辑:事实证明这不是真的。请看选定的答案。)

有没有办法获得内部密钥?我想要它的原因是因为32位密钥比真实世界密钥更有效的内存和速度,这可能是一个(可能)长字符串。

我可以为我的字符串创建一个哈希码注册表,但是如果Java已经可以做到这一点,为什么还要这么做呢。

3 个答案:

答案 0 :(得分:8)

即可。 无法为系统中的每个可能对象获取唯一的32位数字。

对此最简单的证明是,在具有足够内存量的64位JVM上,您可以轻松地拥有超过2 ^ 32个对象:因此您需要超过2 ^ 32个不同的哈希值。但由于您只有32位来存储这些哈希值,因此您不能获得超过2 ^ 32个不同的哈希值。这称为Pidgeonhole principle

另外:HashMap 不会生成“唯一哈希码”:它只是将具有相同哈希码的所有元素存储在同一个存储桶中(在链表中)并进行检查如果必须检索其中一个,则每个人都使用equals()

答案 1 :(得分:2)

强制性链接:Hash table - 只有少数情况甚至允许minimal perfect hashing,而

}实际上有两个因素,它们都与pigeon hole principle相关:

  1. 正如其他人所说,可能会有更多的对象,而不是HashMap所代表的唯一对象:哈希值不能保证唯一。也就是说,散列函数的范围小于唯一对象的范围。
  2. 哈希表中使用的桶数[显着]小于哈希值域:这导致无法保证使用唯一的桶:通常,{{1} }。 (对于42个条目具有2 ^ 32个桶的哈希表几乎不可行;在这种情况下,哈希值的域(如果它大于桶数)在很大程度上是不相关的。)
  3. (另外,a hash code has a strict relationship with object-equality,如果每个对象都有一个“唯一系统哈希码”,那么所述哈希码可以用在对象身份映射中,但不能用于对象相等映射。)

    由于这些原因,在一般的哈希表实现中始终需要collision resolution 。 (OpenJDK 7 HashMap implementation使用链接列表链接方法,最终相等由intbucket_used = hash % bucket_count按顺序决定。)

    虽然JDK实现确实使用内部“哈希混合器”,目的是创建更好的哈希值分布,但这与哈希表如何处理冲突无关,就像原始哈希一样功能,受上述相同规则的约束。

    快乐的编码。

答案 2 :(得分:1)

不,它不会产生不同的哈希码。它将使用相同的哈希代码维护多个条目,并且可以轻松查找具有相同哈希码的所有条目。当您尝试使用该哈希代码查找密钥时,它将检查与所有哈希匹配密钥的相等性,直到找到相等匹配或用完为止。阅读HashMap的代码以了解更多详情。

当可以有超过2个 32 个不同的对象时,您期望HashMap产生一个真正独特的int哈希值?