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方式的优缺点。 
     
     
  • 相关阅读:
    Actioin<T>委托
    StructLayout特性、、、MashalAs
    ibatis.net存储过程:SqlParameterCollection 中未包含带有 ParameterName“@”的 SqlParamer
    Jquery扩展方法
    XML学习
    CSS实现文字阴影
    FTP概述
    Ajax使用PageMethods调用后台方法
    JSP连接SQL2008
    Ajax Sys.UI.DomElement学习
  • 原文地址:https://www.cnblogs.com/sten/p/5721358.html
Copyright © 2011-2022 走看看