最近看了下HashMap的源码,对其中的两个方法不太理解
/**
     * 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);
    }
问题1:为什么还要对对对象的hashCode还要进行一次hash操作
    2:当调用put方法时,跟据hash()返回的值再与表的长度(表的长度是变化的)进行“与”运算,来得到表中的索引,当调用get方法时,也是以上一样的过程,但这时表的长度可能会变化,还能根据对象的hashCode正确得到在表中的索引吗
希望能得到您的指点,谢谢

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【grant999】截止到2008-06-24 14:41:51的历史汇总数据(不包括此帖):
    发帖数:68                 发帖分:1300               
    结贴数:32                 结贴分:640                
    未结数:36                 未结分:660                
    结贴率:47.06 %            结分率:49.23 %            
    楼主该结一些帖子了
      

  2.   

        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); 
        } 
    看注释啊,
    这个函数确保每一个数字在多次的HASH中都要出现相同的结果至于第二个,是把对象的HASH码放入HASHMAP的KEY中,这样,在PUT和get时保证KEY的相同
    应该在一块看
    可以的
      

  3.   

    是的,这两个方法不是程序员调用的,当我们put或者get一个元素时内部会调用这两个方法,当put和get时,都是经过hash-》indexFor()
    在indexFor方法中是根据hash方法返回的结果来与当前表的长度进行“与”运算来得到在表中的索引,感到疑问的是一个元素的hashCode是不变的,经过hash方法后也是不变的,但是表的长度是随时变化的,还能确定在表中的索引吗,
      

  4.   

    楼主赶快结贴,不然老紫竹他不给说啊。想搞清楚整个API?
      

  5.   

    昨天对比了一下HashTable,在HashTable中是用int index = (hash & 0x7FFFFFFF) % tab.length;来获得索引的,每当元素数量要>= threshold时,就会重新rehash(),再根据表的长度重新分配索引
    而在HashMap中,表的长度必须是power of 2,所以会用到下面两个方法,其实就是用hash过的码值来得到length-1(此时length-1最低几位都是1)位的数字,也就是索引
        static int hash(int h) { 
            h ^= (h >>> 20) ^ (h >>> 12); 
            return h ^ (h >>> 7) ^ (h >>> 4); 
        } 
        static int indexFor(int h, int length) { 
            return h & (length-1); 
        }