zoukankan      html  css  js  c++  java
  • HashMap源码分析四

        HashMap源码在jdk1.8中,改动挺大,里面内容已经变的非常复杂了,后面另起博客分析。jdk1.8以前,HashMap一直是数组加链表的数据结构,在数组的某个下标位置,有多次碰撞,则使用链表数据结果存储。在jdk1.8中,引入了红黑二叉查找树的数据结构。刚开始产生碰撞时,碰撞处仍然是链表结构,当链表的长度超过源码设定值8以后,该处的链表将转为红黑二叉树。相比以前,查询效率会高很多,同时代码也变得有一定的复杂度。
     
        HashMap的查询快速的特性是了利用了数组查询快速的特性,把key通过hash求值对应到特定的数组下标。hash碰撞对查询效率,空间使用有很大的影响。当然碰撞没法消除,只能是把碰撞概率越降越低。
     
        idk1.2,jdk1.3的hash计算方式
    int index = (hash & 0x7FFFFFFF) % tab.length;

     

        jdk1.4的hash计算方式

    static int hash(Object x) {
            int h = x.hashCode();
     
            h += ~(h << 9);
            h ^=  (h >>> 14);
            h +=  (h << 4);
            h ^=  (h >>> 10);
            return h;
    }

     

        jdk1.5的hash计算方式
    private static int oldHash(int h) {
        h += ~(h << 9);
        h ^=  (h >>> 14);
        h +=  (h << 4);
        h ^=  (h >>> 10);
        return h;
    }
    
    private static int newHash(int h) {
    
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
    
    static int hash(int h) {
        return useNewHash ? newHash(h) : oldHash(h);
    }
    // -XX:+UseNewHashFunction or -XX:+AggressiveOpts 启动新的hash计算
    private static final boolean useNewHash;
    static { 
        useNewHash = false; 
    }

      

        jdk1.6 的hash计算方式
    static int hash(int h) {
     
         h ^= (h >>> 20) ^ (h >>> 12);
         return h ^ (h >>> 7) ^ (h >>> 4);
     }

     

        jdk1.7的计算方式
    final int hash(Object k) {
        int h = hashSeed;
        // 如果key对象是字符串,则换个方式生成hash值
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
        // 添加生成因子
        h ^= k.hashCode();
    
        // 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);
    }
        jdk1.8的hash计算方式
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

     

        hash求值方式是否优略,主要看hash值是否足够分散。这里可以看出jdk1.2,jdk1.3的求值方式,还挺原始,没做过多的分散处理,相对来说是需要优化的。后面几个hash求值方式,在这里目前还不好详细分析各个hash方式的优缺点。 
     
     
  • 相关阅读:
    怎么查看京东店铺的品牌ID
    PPT编辑的时候很卡,放映的时候不卡,咋回事?
    codevs 1702素数判定2
    codevs 2530大质数
    codevs 1488GangGang的烦恼
    codevs 2851 菜菜买气球
    hdu 5653 Bomber Man wants to bomb an Array
    poj 3661 Running
    poj 1651 Multiplication Puzzle
    hdu 2476 String Painter
  • 原文地址:https://www.cnblogs.com/sten/p/5721358.html
Copyright © 2011-2022 走看看