日期:2014-05-20  浏览次数:20699 次

HaspMap中的那个hash函数是干啥用的?
在HashMap中,在get和put(可能还有其他地方,没记那么多)的时候都对key的hashCode进行hash,返回一个hash然后进行添加或者get。具体是这样的:
int hash = hash(key.hashCode());

然后hash函数的实现是这样:
Java code

/**
     * 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 code

        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }

------解决方案--------------------
哦,我是想说这个函数的意义就是用来确定要取的entry在entry数组中的位置的,至于它为什么这么那我就不知道了,望后面的大牛来指点……
------解决方案--------------------
就是为了纠正hashcode函数的缺陷,因为hashmap的capacity的值是2的指数个,如果两个对象的hashCode值的低位相同,很有可能导致hashCode/capacity的值相同,就会出现冲突。
0101 0000 0000 1111 = 20495
0111 0000 0000 1111 = 28687
假如hashmap的capacity是16,那么20495%16 = 15,28687%16=15,就冲突了
------解决方案--------------------
hashmap数据的存储就是按照hashcode来的,相同hashcode的数据是放在链的同一位置
------解决方案--------------------
hashmap 应该是先用对象的hash值去找对象,找到的值是个数组即具有相同的hash值的,然后再用equal方法去比较二个是否相等,相等的则返回