• ArrayList 源码分析扩容原理


    Java基础知识中面试必问的包括集合,我们不仅要掌握集合语法的使用,也要了解集合体系中每个分支的底层数据结构。掌握了这些对集合已经有了比较深入的认识,接下来就是针对具体的细节深究,本文旨在通过追踪源码带大家初次认识一下ArrayList的扩容原理

    提到ArrayList,我们可以脱口而出底层数据结构是数组,但是如果被追问,刚开始的时候ArrayList存数据时候,数组容量是多少?如果存的数据超过了初始容量的大小,该怎么?-----数组扩容增大容量。 扩容的细节是什么?带着这些疑问我们往下步步探索!

    创建ArrayList有两种方式,使用无参构造器和使用有参构造器,两个办法的扩容逻辑也有区别

    先看结论:
    无参构造器:刚开始数组容量大小为0,第一次扩容到10,第二次扩容到1.5倍-----15,第三次扩容到1.5倍------22,第四次扩容到1.5倍-----33…
    有参构造器:刚开始数组容量为自定义的大小,后面为1.5倍

    无参构造器创建ArrayList的演示代码(在a1处打断点调试

    @Test
        public void Test02(){
            List list = new ArrayList();
            //elementDate初始容量为0
            //第一次扩容到10
            list.add("a1");  //断点
            list.add("a2");
            list.add("a3");
            list.add("a4");
            list.add("a5");
            list.add("a6");
            list.add("a7");
            list.add("a8");
            list.add("a9");
            list.add("a10");
    
            //需要扩容到15
            list.add("a11");   //断点
            list.add("a12");
            list.add("a13");
            list.add("a14");
            list.add("a15");
    
            //第三次扩容到22
            list.add("a12");  //断点
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    现追踪第一次扩容底层执行流程,看看如何给数组分配大小并且存数据 a1
    在这里插入图片描述
    在这里插入图片描述
    接下来该第二次扩容了,我们先不看源码,先根据上面的逻辑自己分析一下怎么实现的。

    1. 进入add(E e)方法{ 调用执行方法ensureCapacityInternal(参数为 10+1)}
    2. 调用执行方法ensureExclicitCapacity( CaculateCapacity(10,11))
    3. 调用执行方法CaculateCapacity(10,11){
      if(11== 0)不成立 所以直接 return 11}
    4. 调用执行方法ensureCapacityInternal(参数为 11)
    5. 调用执行方法ensureExclicitCapacity( CaculateCapacity(10,11))
    6. 调用执行方法ensureExclicitCapacity(参数为11){
      if(11- 10 >0)成立--------->说明需要11个,现在只提供10个,需要扩容}
    7. 调用执行方法grow(11){
      oldCapacity =10
      newCapacity = 10 + 10/2 = 15
      if(15-11 < 0 ) 不成立-------->说明 提供的15个空间 足够 所需要的最少11个 的条件
      执行扩容方法Arrays.copyOf(10,15)
    8. 总共15个空间已经扩容结束,elementData[10]存入元素 a11

    经过debug调试验证,完全符合我们的推测。

    拓展:解释一下图示方法
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Day48 力扣动态规划 : 647. 回文子串 |516.最长回文子序列 |动态规划总结篇
    HTTPS、SSL/TLS,HTTPS运行过程,RSA加密算法,AES加密算法
    【打卡】21天学习挑战赛—RK3399平台开发入门到精通-day1
    【Unity实战100例】Unity幸运大转盘之概率可控
    Netty2
    百度地图,地市区域描边
    查找算法——顺序查找
    【DockerCE】Docker-CE 20.10.18正式版发布
    11. 常用类
    多测师肖sir_高级金牌讲师_python之作业006
  • 原文地址:https://blog.csdn.net/heng000000/article/details/126531026