【问题标题】:Java HashMap Hashing function [closed]Java HashMap 哈希函数
【发布时间】:2013-03-19 03:05:27
【问题描述】:

我正在通过 Java 的 HashMap hash() 实现,如下所示

final int hash(Object k) {
            // some checks
            h ^= k.hashCode();
            // 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);
                   // >>> is Unsigned right shift
    }

我不知道为什么要添加下面的代码,这样做有什么好处?

        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);

或者,如果我从实现中删除上述代码,让我重新提出我的问题,有什么缺点?我了解它如何避免碰撞的机会,但不确定“确切”如何?

有人可以通过举个例子帮助我理解,并解释使用和不使用上述代码将如何工作吗?

【问题讨论】:

  • 评论的哪一部分你不明白?
  • 如何使用">>>" 运算符来避免冲突,即使键返回相同的值? 7和4的意义是什么?使用 13 和 7 或其他整数而不是 7 和 4 更好吗??
  • @Lav:常数是通过实验确定的;对他们没有真正的意义。 (实际上,对于散列,使用没有真实模式的临时数字通常是一个 的想法)。但问题不在于两个键具有完全相同的哈希码,而是当两个键具有相同的哈希码 mod 2 的小幂时减少冲突。
  • 好的,我感觉更好了,可能是一个具体的例子可以帮助更好?
  • 它确保在每个位位置仅相差恒定倍数的 hashCode 具有有限数量的冲突。 (在默认负载因子下约为 8)

标签: java collections hash hashmap


【解决方案1】:

Java 哈希表实现不是将表的大小调整为素数大小,而是大小的二次幂。这允许它使用快速位掩码而不是昂贵的余数运算,这通常是一件好事,但缺点是特别糟糕的散列函数可能比平时有更多的冲突。您引用的代码以最小化额外冲突的方式混合了哈希的位。

【讨论】:

  • 是的,我理解“以最小化额外冲突的方式混合散列的位”..我的问题是冲突以何种方式最小化......以及为什么像 20 这样的整数, 12, 7, 4 被使用,而不是一些......寻找一个返回相同哈希码但上述代码的哈希码实现示例 >>> 采用不同的桶
  • 整数是在031 之间的可能数字之间任意选择的,这是您唯一可以转换到的数字,其中涉及一些实验。它们没有任何特定的意义。
猜你喜欢
  • 1970-01-01
  • 2020-02-09
  • 2015-07-06
  • 2012-09-26
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
相关资源
最近更新 更多