栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

HashMap底层分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

HashMap底层分析

1. resize()方法主要用于对数组进行初始化 或 扩容

2. 初始化:HashMap底层数组初始化采用延时机制,被推迟到put()方法中,但主要还调用resize()方法来完成。HashMap底层数组初始化两种情况,创建HashMap对象时:指定初始容量 和 不指定初始容量。

  • 如果指定初始容量,则这个初始化容量会被tableSizeFor()方法进行调整,以确保数组长度一定为2的整数幂。

  • 不指定初始容量,则使用默认初始化容量16

3. 扩容:数组每次扩容为原来的两倍,并且数组扩容后,需要将原数组的节点对象转移到扩容数组中。

//数组长度达到阈值
if (++size > threshold)
	//扩容
    resize();
final Node[] resize() {
	//将table数组赋给oleTab,用oldTab来记录
    Node[] oldTab = table;
    //用oldCap记录原数组长度
    int oldCap = (oldTab == null) ? 0 : oldTab.length;
    //用oldThr记录阈值(如果创建hashMap对象时指定了初始容量,则这个threshold为经过tableSizeFor()处理过的初始容量值,具体可以看HashMap构造函数)
    int oldThr = threshold;
    //分别用newCap、newThr来记录扩容后的数组长度和阈值
    int newCap, newThr = 0;
    
    //原数组oldTab长度大于0,则扩容
    if (oldCap > 0) {
    
    	//oldTab >=最大限制容量,则threshold取最大值,并返回oldTab
        if (oldCap >= MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return oldTab;
        }
        
        //反之,oldTab,oldThr均扩容为原来的两倍,并分别赋给newTab 和 newThr
        else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                 oldCap >= DEFAULT_INITIAL_CAPACITY)
            newThr = oldThr << 1; // double threshold 双倍阈值
    }
    
    //数组初始化(创建hashMap对象时指定初始容量),长度为经过tableSizeFor()处理过的初始容量值
    else if (oldThr > 0) // initial capacity was placed in threshold
		
        newCap = oldThr;
     
    //数组初始化(创建hashMap对象时不指定初始容量),长度为默认初始化容量16
    else {               // zero initial threshold signifies using defaults
        newCap = DEFAULT_INITIAL_CAPACITY;
        //阈值newThr = 16 * 0.75 = 12
        newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
    }
    
    
    if (newThr == 0) {
        float ft = (float)newCap * loadFactor;
        newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                  (int)ft : Integer.MAX_VALUE);
    }
    //newThr记录完后,反过来赋给threshold
    threshold = newThr;
    @SuppressWarnings({"rawtypes","unchecked"})
    	//创建一个空数组,长度为原来的两倍(如果是首次初始化,则长度为它的初始容量)
        Node[] newTab = (Node[])new Node[newCap];
    table = newTab;
    
    //如果原数组oldTab不为空,将原数组oldTab的node节点元素,移动到扩容后的数组newTab中
    if (oldTab != null) {
        for (int j = 0; j < oldCap; ++j) {
            Node e;
            if ((e = oldTab[j]) != null) {
                oldTab[j] = null;
                if (e.next == null)
                    newTab[e.hash & (newCap - 1)] = e;
                else if (e instanceof TreeNode)
                    ((TreeNode)e).split(this, newTab, j, oldCap);
                else { // preserve order
                    Node loHead = null, loTail = null;
                    Node hiHead = null, hiTail = null;
                    Node next;
                    do {
                        next = e.next;
                        if ((e.hash & oldCap) == 0) {
                            if (loTail == null)
                                loHead = e;
                            else
                                loTail.next = e;
                            loTail = e;
                        }
                        else {
                            if (hiTail == null)
                                hiHead = e;
                            else
                                hiTail.next = e;
                            hiTail = e;
                        }
                    } while ((e = next) != null);
                    if (loTail != null) {
                        loTail.next = null;
                        newTab[j] = loHead;
                    }
                    if (hiTail != null) {
                        hiTail.next = null;
                        newTab[j + oldCap] = hiHead;
                    }
                }
            }
        }
    }
    返回newTab
    return newTab;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/301058.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号