`
marystone
  • 浏览: 7478 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

HashMap hash方法分析

    博客分类:
  • Java
阅读更多
HashMap 中hash table 定位算法:
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);

其中indexFor和hash源码如下:
    /**
     * 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);
    }

    /**
     * Returns index for hash code h.
     */
    static int indexFor(int h, int length) {
        return h & (length-1);
    }

indexFor这个方法论坛中已有人分析过,这里就不再分析。
现在分析一下hash算法:
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);

假设key.hashCode()的值为:0x7FFFFFFF,table.length为默认值16。
上面算法执行如下:



得到i=15

其中h^(h>>>7)^(h>>>4) 结果中的位运行标识是把h>>>7 换成 h>>>8来看。

即最后h^(h>>>8)^(h>>>4) 运算后hashCode值每位数值如下:
8=8
7=7^8
6=6^7^8
5=5^8^7^6
4=4^7^6^5^8
3=3^8^6^5^8^4^7
2=2^7^5^4^7^3^8^6
1=1^6^4^3^8^6^2^7^5
结果中的1、2、3三位出现重复位^运算
3=3^8^6^5^8^4^7     ->   3^6^5^4^7
2=2^7^5^4^7^3^8^6   ->   2^5^4^3^8^6
1=1^6^4^3^8^6^2^7^5 ->   1^4^3^8^2^7^5

算法中是采用(h>>>7)而不是(h>>>8)的算法,应该是考虑1、2、3三位出现重复位^运算的情况。使得最低位上原hashCode的8位都参与了^运算,所以在table.length为默认值16的情况下面,hashCode任意位的变化基本都能反应到最终hash table 定位算法中,这种情况下只有原hashCode第3位高1位变化不会反应到结果中,即:0x7FFFF7FF的i=15。
  • 大小: 238.6 KB
分享到:
评论
2 楼 337240552 2012-08-01  
讲到后面我也不理解了
1 楼 BruceXX 2012-05-09  
看了下,觉得有点迷糊,一直在思考为什么采用这种算法,


不知道
引用
其中h^(h>>>7)^(h>>>4) 结果中的位运行标识是把h>>>7 换成 h>>>8来看。


这句话是什么意思。。

引用

即最后h^(h>>>8)^(h>>>4) 运算后hashCode值每位数值如下:
8=8
7=7^8
6=6^7^8
5=5^8^7^6
4=4^7^6^5^8
3=3^8^6^5^8^4^7
2=2^7^5^4^7^3^8^6
1=1^6^4^3^8^6^2^7^5


这些也并不是实际数值吧,只是代表位有参与计算

引用
结果中的1、2、3三位出现重复位^运算
3=3^8^6^5^8^4^7     ->   3^6^5^4^7
2=2^7^5^4^7^3^8^6   ->   2^5^4^3^8^6
1=1^6^4^3^8^6^2^7^5 ->   1^4^3^8^2^7^5


咋就变成这样了哩,还请解释下,多谢~~

相关推荐

    hashmap中hash函数的构造问题

    通过上述分析,我们可以看到不同哈希函数构造方法的特点和优缺点。选择合适的哈希函数对于提高`HashMap`的性能至关重要。在实际应用中,可以根据具体场景的需求来选择最合适的哈希函数,或者通过组合多种哈希函数来...

    HashMap扩容时的rehash方法中(e.hash & oldCap) == 0算法推导.docx

    这里我们将详细讨论在HashMap扩容时`rehash`方法中`(e.hash & oldCap) == 0`这一算法的推导。 首先,`e.hash`是HashMap中某个元素的哈希值,它由键对象的`hashCode()`方法计算得出,通常是键对象的哈希码右移16位后...

    HashMap-hash原理

    ### HashMap的Hash原理详解 #### 一、概述 在Java编程语言中,`HashMap`是实现`Map`接口的...通过以上分析,我们可以更加深入地理解`HashMap`内部的工作机制,这对于理解和优化基于`HashMap`的应用程序具有重要意义。

    HashMap之resize()方法源码解读.docx

    HashMap之resize()方法源码解读 HashMap的resize()方法是HashMap中最核心的方法之一,该方法负责扩容HashMap的容量,以便存储更多的键值对。下面我们将对HashMap的resize()方法进行源码解读,了解其扩容机制和原理...

    HashMap之put方法源码解读.docx

    在本文中,我们将对 HashMap 的 put 方法的源码进行详细解读,分析put 方法源码中的内在逻辑关系,欣赏源码独特之美,从中学习更为精致的编程思维。 首先,让我们看一下 put 方法的源码: ```java public V put(K ...

    HashMap源码分析

    当向 HashMap 中插入一个键值对时,会先计算键的哈希值,通过哈希值与数组长度进行按位与运算(hash % array.length),得到的余数值作为数组的索引。如果该索引位置已经有元素存在,说明发生了哈希冲突,此时会将...

    Hashmap详解

    下面我们将深入探讨 HashMap 的数据结构、 put 方法的实现细节和 Hash 码的计算过程。 HashMap 的数据结构 HashMap 的数据结构可以分为两部分:数组和链表。数组是 HashMap 的基本结构,链表是数组元素的具体实现...

    HashMap 分析

    紧接着,文档给出了HashMap中不同索引位置桶内的元素的具体信息,包括元素的哈希值(hash)和值(value)。例如,table[51]索引位置有两个元素,它们的哈希值分别为1635379和1577523,对应的值分别为63和70。通过...

    Java HashMap类详解

    本资源详细介绍了 Java 中的 HashMap 类,包括其实现机制、Hash 存储机制、集合存储机制等方面的知识点。 1. HashMap 和 HashSet 的关系 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,虽然...

    Java集合专题总结:HashMap 和 HashTable 源码学习和面试总结

    Java集合专题总结:HashMap和HashTable源码...本文总结了HashMap和HashTable的源码学习和面试总结,涵盖了它们的存储结构、构造方法、get和put方法的源码分析、Hash表的特点和缺点、HashTable和HashMap的区别等内容。

    HashMap总结

    HashMap 是基于哈希表(Hash Table)实现的,哈希表是一个存储键值对的数据结构,它使用哈希函数将键转换为索引,然后将键值对存储在数组中。HashMap 使用链表来解决哈希冲突的问题,即当两个键的哈希值相同时,...

    HashMap put方法的源码分析

    通过以上分析,我们可以看到Java 1.8 HashMap的put方法在处理哈希冲突时,不仅使用了链表,还在节点数量达到一定阈值时切换为红黑树,有效提高了数据结构的性能。同时,通过扩容机制,HashMap能够保持较低的哈希冲突...

    HashMap-master.zip_hash

    标题"HashMap-master.zip_hash"可能指的是一个关于HashMap实现或优化的项目,其中包含了哈希函数的设计和分析。 哈希表的核心思想是通过哈希函数将键(Key)映射到数组的特定位置,使得我们能够以近乎常数的时间...

    通过 HashMap、HashSet 的源代码分析其 Hash 存储机制1

    本文将深入分析HashMap和HashSet的哈希存储机制。 首先,HashSet是一个基于哈希表实现的无序不重复元素集合。它通过计算对象的哈希码来决定元素的存储位置,从而确保了快速的查找和插入操作。在HashSet中,元素的...

    Java中HashMap的工作机制

    如果在计算出的位置上有现成的Entry存在(即发生哈希冲突),HashMap将遍历这个冲突链,检查是否已经存在一个键与新传入的键相等(通过调用equals()方法)。如果存在,它将替换掉旧的值,并返回旧值。如果不存在,它...

    HashMap的数据结构

    HashMap的工作原理基于哈希函数,它将键(Key)转化为一个哈希码(Hash Code),这个哈希码用于确定键值对在数组中的位置。当两个不同的键经过哈希函数处理后得到相同的哈希码时,就会发生哈希碰撞。为了解决这个...

    HashMap介绍和使用

    final int hash; Entry,V> next; ... } ``` 当向HashMap中添加元素时,系统会根据键的哈希值计算出其在数组中的位置,并将元素存放在该位置。如果该位置已有元素,则将新元素以链表形式连接到已有元素之后。 ##...

Global site tag (gtag.js) - Google Analytics