HashMap的hash原理

public static void main(String[] args) {
        String[] keyArray = {"Terra", "Jonas", "Liron", "Billy", "Andy"};
        // 假设为刚new的HashMap,那么它的默认长度即为16
        int n = 16;
        for (int i = 0; i < keyArray.length; i++) {
            int hash = hash(keyArray[i]);
            System.out.print("key:" + keyArray[i] + ",  hash:" + hash);
            // 来自源码 if ((p = tab[i = (n - 1) & hash]) == null)
            System.out.println(",  index:" + ((n - 1) & hash));
        }
        // 解: n必然为2的倍数,那么n-1的二进制的低位便都是1, 如1(2^0 -1 ): 01, 3(2^2 -1 ):11, 15(2^4-1): 1111
        // 那么无论hash值是多少,按位运算(&)只会在低位的N位内有效:
        // hash("Terra") = 80698687
        // 80698687: 100110011110101110100111111
        // 16 - 1//: 000000000000000000000001111
        // result//: 000000000000000000000001111 = 15
        // 使得所有的值被分布到0-15的位置上去。
        // 我们注意到这样会上面的数组会出现2个13,这就是哈希冲突,HashMap将13转为单链表形式将这两个值一并存起。
        // 猜想HashMap排列如下:
        // ____1,_____4,____13,____15
        // Billy, Liron, Jonas, Terra
        // NULL, __NULL, _Andy, _NULL
    }

    /**
     * copy from HashMap -JDK1.8
     */
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
  // 等等,好像要说的是上面这个方法才对...

 

posted @ 2018-12-30 22:03  四方田春海  阅读(171)  评论(0编辑  收藏  举报