HashMap中resize()方法源码详解(一)

HashMap中的resize()方法作用是初始化或者加倍容量,方法内部会自动判断当前进行的是初始化还是扩容操作。
扩容操作是通过“新建一个hash表,然后将旧表中的内容重新散列复制到新表中”这种方式实现的。
源码中大概可以分为两部分:
第一部分主要用于判断当前操作的类型(初始化or扩容)并且计算出新生成的表的容量和阈值。
第二部分只用于扩容操作时,将旧表中的元素重新散列放入新表。
本文只讲第一部分,下面直接放代码:代码是连续的,分开截图仅仅是为了方便。

    // oldTab----当前容量超过阈值需要扩容的表(旧表),如果HashMap尚未初始化则table==null
        Node<K,V>[] oldTab = table;
        // oldCap----旧表的长度
        int oldCap = (oldTab == null) ? 0 : oldTab.length;
        // oldThr----在旧表中,当长度达到该值时需要进行容量调整,值为(旧表的容量 * 负载因子)
        int oldThr = threshold;
        // newCap----新表长度     newThr----新表长度达到该值时需要进行下一次容量调整,值为(新表的容量 * 负载因子)
        int newCap, newThr = 0;
        // 分支1
        // 通过旧表长度是否大于0判断是初始化还是扩容,如果大于0说明正在进行扩容而不是初始化。
        if (oldCap > 0) {
            // 分支1.1
            // 以旧表长度是否大于等于最大长度判断是否还可以扩容
            // 不能继续扩容时
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            }
            // 分支1.2
            // 当还可以扩容时
            // 再通过新表的容量与最大容量比较,以确定是否还有下一次扩容
            // #######疑问标记######## oldCap >= DEFAULT_INITIAL_CAPACITY这个判断有什么意义?没看懂
            else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                    oldCap >= DEFAULT_INITIAL_CAPACITY)
                // 若还可以进行下一次扩容,那么将新表下次扩容的阈值也调整为旧表阈值的两倍
                newThr = oldThr << 1; // double threshold
        }
        // 分支2
        // 当旧表长度不大于0时,通过oldThr是否大于0来判断是默认容量初始化还是给定容量初始化,当为给定容量初始化时
        // 是用threshold这个属性存放的给定的容量的数值,详见构造器
        else if (oldThr > 0) // initial capacity was placed in threshold
            newCap = oldThr;
        // 分支3
        // 默认容量初始化
        else {               // zero initial threshold signifies using defaults
            newCap = DEFAULT_INITIAL_CAPACITY;
            newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }
        // 进入下面这个if条件语句有且仅有两种情况:
        // (1)当程序运行到1.2分支语句确没有通过其中的判断时表明:此次扩容为最后一次扩容,扩容之后大小为HashMap最大容量
        // (2)当程序进入2分支时则此次方法调用为给定数值初始化
        // 以上两种情况都未指定新表的扩容阈值,即newThr为初始值0
        if (newThr == 0) {
            float ft = (float)newCap * loadFactor;
            // 若为第(1)种情况,不存在下一次扩容,则阈值应设置为Integer.MAX_VALUE
            // 若为第(2)中情况,阈值即为 新表容量 * 负载因子
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                    (int)ft : Integer.MAX_VALUE);
        }
        threshold = newThr;
        // ------以上所有分支都是为了判断新表的容量和阈值---------
          

想说的都在注释里了,本人水平有限,如果有错误欢迎大佬指教。

··原创文章,转载请指明作者及原文链接。

你可能感兴趣的:(JAVA源码)