【问题标题】:HashMap hash function- Binary operatorHashMap 哈希函数 - 二元运算符
【发布时间】:2020-02-09 23:20:37
【问题描述】:

我正在浏览HashMap的源代码,但是二进制运算符很混乱。

我确实理解以下的一般目的,公平分配并将 hashCode 带入存储桶限制。

有人能解释一下这里的 cmets 吗?现在这样做有什么好处?

/**
     * Computes key.hashCode() and spreads (XORs) higher bits of hash
     * to lower.  Because the table uses power-of-two masking, sets of
     * hashes that vary only in bits above the current mask will
     * always collide. (Among known examples are sets of Float keys
     * holding consecutive whole numbers in small tables.)  So we
     * apply a transform that spreads the impact of higher bits
     * downward. There is a tradeoff between speed, utility, and
     * quality of bit-spreading. Because many common sets of hashes
     * are already reasonably distributed (so don't benefit from
     * spreading), and because we use trees to handle large sets of
     * collisions in bins, we just XOR some shifted bits in the
     * cheapest possible way to reduce systematic lossage, as well as
     * to incorporate impact of the highest bits that would otherwise
     * never be used in index calculations because of table bounds.
     */
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

如果有人能帮助我理解它,那将是一个非常大的帮助。

这不是重复的,因为其他问题与 Java 8 之前的哈希实现有关。

提前致谢

【问题讨论】:

  • 具体哪一部分你有理解困难?
  • 对位运算符不太满意。我的意思是我知道他们是怎么做的,比如什么是左移,什么是右移,什么是异或,但总的来说,它如何帮助实现散列的预期目的,而评论根本没有帮助。 “哈希的高位到低位”,“仅在当前掩码之上的位变化的哈希集总是会发生冲突”,“所以我们应用了一个变换,将高位的影响向下传播”

标签: java hash java-8 hashmap hash-collision


【解决方案1】:

hashCode() 返回一个 32 位宽的 int

在内部,HashMap 将对象保存在 pow(2, n) bucketsbins 中。 n 的值可以变化——细节在这里并不重要;重要的是n 通常远小于 32(哈希中的位数)。

每个对象都被放入其中一个桶中。为了获得良好的性能,最好将对象均匀地分布在桶中。这就是对象哈希的用武之地:选择存储桶的最简单方法是获取对象哈希码的最低n 位(使用简单的按位与)。但是,这只会使用最低的n 位并忽略其余的散列。

在 cmets 中,作者认为这是不可取的。他们引用了已知用例的示例,在这些用例中,对象哈希在比特上会系统性地不同,而不是最低的n。这会导致系统性碰撞,而系统性碰撞是个坏消息。

为了部分解决这个问题,他们实施了当前的启发式方法:

  • 保持哈希的前 16 位不变;
  • 用前 16 位和后 16 位的XOR 替换后 16 位。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2015-07-06
  • 1970-01-01
  • 2017-04-03
相关资源
最近更新 更多