当前位置: 首页 > 面试题库 >

HashMap中的Hash方法

杨安歌
2023-03-14
问题内容
  /**
    * Applies a supplemental hash function to a given hashCode, which
    * defends against poor quality hash functions.  This is critical
    * because HashMap uses power-of-two length hash tables, that
    * otherwise encounter collisions for hashCodes that do not differ
    * in lower bits. Note: Null keys always map to hash 0, thus index 0.
    */
   static int hash(int h) {
       // This function ensures that hashCodes that differ only by
       // constant multiples at each bit position have a bounded
       // number of collisions (approximately 8 at default load factor).
       h ^= (h >>> 20) ^ (h >>> 12);
       return h ^ (h >>> 7) ^ (h >>> 4);
   }

谁能详细解释这种方法,谢谢。


问题答案:

设计通用哈希码的问题之一是,您将所有这些工作都放在了确保良好的位扩展上,然后有人来使用并以完全撤消的方式使用它。

让我们以一个带有X和Y(均为整数)的坐标类的经典示例为例。

这是一个经典的示例,因为人们会用它来证明这X ^ Y不是一个很好的哈希码,因为通常会有多个对象,其中X == Y(所有哈希都为0)或X和Y为Y和X的对象其他(将散列相同)和其他情况下,我们最终得到相同的散列码。

归结为一个事实,虽然整数的可能范围涵盖40亿个值,但在99%的使用中,它们最多最多不到几百或几万。我们永远无法避免尝试在40亿个可能的结果中分散18个四十亿可能的值,但是我们可以努力使我们实际看到的值减少冲突的可能性。

现在,(X << 16 | X >> 16) ^ Y在这种情况下做得更好,将来自X的位分散更多。

不幸的是,如果使用此哈希% someBinaryRoundNumer来索引表(甚至% someOtherNumber在较小程度上),则对于低于X的值(someBinaryRoundNumber我们可以预期是最常见的),此哈希有效return Y。

我们所有的辛苦工作被浪费了!

所使用的重新哈希方法是使用这种逻辑进行哈希方法,效果略好。

值得一提的是,过于批评这种(X << 16 | X >> 16) ^ Y方法是不公平的,因为对哈希的另一种使用可能具有优于给定替代方法的形式。



 类似资料:
  • 问题内容: 有人可以向我解释静态HashMap#hash(int)方法吗? 产生均匀分布的哈希的背后的理由是什么? 一个例子将使它更容易消化。 澄清 我知道运算符,真值表和按位运算。我只是无法真正解码实现,也无法真正评论。甚至是背后的原因。 问题答案: 是逻辑右移(无符号扩展)(JLS 15.19 Shift Operators ),并且是按位异或(JLS 15.22.1 Integer Bitw

  • 我试图用这个键得到一个值。我正在使用get()方法。我的密钥是由int和String组成的对象。所以我提出反对 我收到了空的。当我查看去bug模式或打印密钥集时,我收到类似的消息 虽然我的钥匙应该是 为什么键看起来像这样而不是以及如何使用键获取值? 我在键中覆盖了字符串methid。它看起来更好,但我仍然有空值,我相信有一些价值。

  • 可能重复: HashMap#hash(int)方法的解释 有人能详细解释一下这个方法吗,谢谢。

  • 本文向大家介绍js数组去重的hash方法,包括了js数组去重的hash方法的使用技巧和注意事项,需要的朋友参考一下 对于 JavaScript 数组去除重复项,现在有多种方法,其中一种是hash,如下: 但是该方法并不严谨,无法区分数字 1 和 字符串 '1' 修改一下,加上数据类型判断: 至少现在对5种原始数据类型的值可以准确去重了,对某些引用类型的值──数组,函数,也可以,但是对象类型──{"

  • 本文向大家介绍Hash表处理冲突的方法相关面试题,主要包含被问及Hash表处理冲突的方法时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 开放定址法 为产生冲突的地址求得一个地址序列(),其中。其中m为表的长度,而增量有三种取值方法,线性探测再散列,平方探测再散列,随即探测再散列。 链地址法 将所有Hash地址相同的记录都链接在同一链表中 再Hash法 同时构造多个不同的Hash函数,当产生

  • 问题内容: 有一些实用方法可以创建like 及其重载。 但是,这种方法不存在或在类。 有没有更好的方法可以做到这一点,或者Guava认为这样的映射始终是恒定映射,并且是最好的选择,并且不需要为它提供实用程序。 问题答案: 你为什么要那些定期或?您可以这样做: 用的东西是,它是多一点点麻烦创造; 您首先需要制作一个,然后将键值对放入构建器中,然后调用它来创建。如果要使用单个键值对创建,则该方法可以缩