ArrayList源码解析,底层结构+扩容机制,通俗易懂

1.4ArrayList源码解析

1.4.1.无参构造器创建ArrayList

1.首先创建一个ArrayList,并采用无参构造器进行初始化对象。
在这里插入图片描述

当我们在第12行打一个断点追溯进去,无参构造器当中的代码为:this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA
在这里插入图片描述

向上翻阅源码,会发现其实ArrayList底层就是一个Object类型的数组elementData,来存放我们add进去的元素,而DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是一个空数组,当我们使用无参构造器创建ArrayList对象的时候,就会初始化elementData为空的数组。

在这里插入图片描述

2.执行list.add(“a”),我们一起追溯进去看看ArrayList到底是怎么样进行大小扩容的。

在这里插入图片描述

当执行list.add()方法的时候,发现会执行ensureCapacityInternal方法,并且传入的参数为size+1,size表示的是ArrayList的长度,刚开始的size值为0,为了能让他执行当前的add方法,则需要给他先加上一个长度,才能添加当前的这个元素。

在这里插入图片描述

接着我们继续step into ensureCapacityInternal这个方法,接着step into calculateCapacity()方法,calculateCapacity方法传入的参数为数组以及当前所需最小容量。

在这里插入图片描述

进入到方法以后,会先坐一个判断,如果当前elementData数组为null,则返回DEFAULT_CAPACITY(10)和 minCapacity当中的最大值,则也说明了当我们使用无参构造器创建ArrayList对象的时候,第一次扩容的大小为10,默认我们第一次就需要10个大小。

在这里插入图片描述

接着退出calculateCapacity()方法,进入ensureExplicitCapacity()方法,有一个modCount变量记录着我们对list集合进行了几次操作。接着会执行第238行的if语句,我们的minCapacity为刚刚方法的返回值10,而elementData.length为0,所以会执行grow()方法。
在这里插入图片描述

接着step into grow()方法,这个方法也可以算是扩容的核心算法了,首先将当前数组的长度赋值给oldCapacity,接着执行259行,将1.5倍的旧容量赋值给新的容量,这也就是我们所知道的ArrayList第二次进行扩容的时候,是第一次的1.5倍大小

在这里插入图片描述

但其实当第一次进入grow()方法的时候,old和new都为0,所以260行的if语句为true,会把第一次扩容的10赋给newCapacity

在这里插入图片描述

接着再执行第265行Arrays.copy(),将原本的elementData 复制赋值回去,通过debug可以看出此时的elementData数组为10个null值。
在这里插入图片描述

接着会继续执行add方法剩下的语句,也就是将元素添加进数组当中。

在这里插入图片描述

此时list集合当中已经有一个a,这个时候程序会继续执行add(b)。

在这里插入图片描述

后面就是重复的步骤,当list添加了10个元素以后,就会继续扩容,将newCapacity赋值为oldCapacity的1.5倍,也就是第二次扩容会有15个空间。这边就不再继续演示源码过程,直接贴上添加第十一个元素的时候,list集合的情况。

在这里插入图片描述

1.4.2.有参构造器创建ArrayList

上面演示的是通过无参构造器进行集合的创建。还有另一种方法,就是通过有参构造器来指定capacity的初始化大小

1.初始化大小为15

在这里插入图片描述

2.调用有参构造器,通过源码就可以看出在第153行,就直接把数组的长度设置为我们传进去的值。接着后面扩容的步骤也是oldCapacity的1.5倍
在这里插入图片描述

1.4.3有参构造和无参构造总结

  • 如果是有参构造器,初始大小为传入的容量。往后的每次扩容都为原来的1.5倍
  • 如果是无参构造器,第一次扩容大小为10。往后的每次扩容都为原来的1.5倍
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的小新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值