java - 理解 java 8 中 HashMap 类的 hash() 方法的方法注释

标签 java data-structures hash hashmap

 /**
     * 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);
}

下面是JDK 1.6的早期版本

/**
     * 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);
    }

有人能解释一下应用这种散列比在早期版本的 java 中所做的有什么好处吗?这将如何影响 key 分发的速度和质量,我指的是在 jdk 8 中实现的新哈希函数以及它是如何实现这一点以减少冲突的?

最佳答案

hashCode 方法表现相当糟糕的情况下,HashMap 的性能会急剧下降。例如,假设您的 hashCode 方法只生成了一个 16 位数。

这通过异或自身右移16的散列码解决了这个问题。如果在此之前人数分布均匀,它应该仍然如此。如果它很糟糕,这应该会有所改善。

关于java - 理解 java 8 中 HashMap 类的 hash() 方法的方法注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36554000/

相关文章:

C++:管理一组对象,以便持有的对象可以访问持有它们的数据结构

c - 哈希表的数字折叠算法

ruby 。合并嵌套哈希而不覆盖

c++ - 如何将 GUID 和 64 位时间戳散列到另一个 GUID

java - Hibernate:在多对多关系中添加实体会导致另一个实体不必要的更新

java - 创建一个不能通过 file.delete() 删除的文件

algorithm - 在 N 个列表中查找匹配项的有效方法?

java - 如何使用 PBKDF2 在 Java 和 Ruby 中生成相同的安全哈希

java - 如何将图像从 Android 上传到 Google Cloud (Java)?

java - Spring 4安全访问被拒绝(用户不是匿名的)