ArrayList源码分析--底层扩容机制

ArrayList源码分析–底层扩容机制

最近在复习Java基础知识,故写此博客记录

先说结论如果我们在初始集合时使用无参构造形式,那么ArrayList的初始大小为0,当我们第一次添加数据时,数组大小为10,后续每次添加数据时(我们规定每次只添加一个数据,原因我们后面会说到)如果容量不够,则集合扩容为原来的1.5倍数 Plus:此程序运行的环境为jdk15,不过8版本机制和这个大体上差不多

以下为演示过程
首先我们写这样一个简单的程序:
演示图片1
我们开始调试程序。

首先,我们先按 Ctrl+A进入查看AyyayList的空构造方法
在这里插入图片描述
看不懂没关系,我们往上翻来找这个DEFAULTCAPACITY_EMPTY_ELEMENTDATA
在这里插入图片描述
从这里我们就可以发现,其实这段话的含义就是把ArrayList初始化为一个空数组,让然后我们跳出来继续看。
在这里插入图片描述
此时集合的size(大小)为0,也印证了我们的想法

下面我们来看add方法

首先时对int数据类型的装箱,变成integer类型,然后我们跳出来继续看
在这里插入图片描述

在这里插入图片描述
这里的modCount记录着我们的操作次数我们先不管它,方法里面又含有一个add方法,e就是我们要添加的元素,elementData是我们要操作的数组,size是现在集合的大小,我们进入这个add方法

首先是检验数组的容量是否足够用于扩容,即检验下标是否等于数组容量,如果为true,说明容量已经不足了,false则表示还有容量也就自然不需要执行扩容操作了,这里为true,我们执行扩容操作
在这里插入图片描述
这个时候我们才开始执行扩容操作grow方法
在这里插入图片描述

这里的minCapacity是现在集合最小需要的容量
oldCapacity:数组现在的容量,
在这里插入图片描述
然后判断集合大小是否大于0或者不为空,否,我们进入这个看起来很长的方法
在这里插入图片描述
这里操作其实很显而易见,还记得我们之前的结论吗?第一次扩容(这里我们讨论的是无参构造的情况),扩容后的大小为10。
这里做的就是这一步操作,如果我们需要的容量(此时是1)小于10,那么我们就新创建一个大小为10的数组,然后赋值给elementData也就是我们要操作的数组,如果需要的容量大于10,比如为x(x>10),那么就创建一个大小为x的数组,然后将它赋值给elementData,OK结束。

至此我们一直出栈,发现elementData的大小确实变成了10,将值e放入数组集合的第一个位置,然后size+1。
在这里插入图片描述

至此我们的第一次扩容工作就结束啦。是不是觉得很简单呢。
后续的9次循环,就是正常添加数据,并不会触发扩容操作,原因上面我们已经说过了,判断语句是这句话。
在这里插入图片描述
好,接下来9次循环我们就跳过,我们来看下一次容量不够时程序执行的操作。
此时集合容量还是10,但我们即将插入第11个数据
在这里插入图片描述
前面一堆跟上面一样的操作我就不再讲了,直接开讲不一样的。

首先是程序检测到集合已满不足以添加新数据,即将执行grow方法
在这里插入图片描述
此时我们的集合已经大于0了,开始执行不一样扩容的操作
在这里插入图片描述
我们首先进入ArraysSupportnewLength方法,这里有三个参数
oldLengthminGrowthprefGrowth
oldLength时原来集合的大小,minGrowth是集合最小需要扩容的大小,值为:需要添加的数据数+集合的原来大小,prefGrowth是集合现在大小的一半,考虑到有些朋友可能不明白>>符号的意思,这里我找了一篇文章大家可以参考看一下Java中的>>,>>>

好啦我们继续
又进入了一个方法

在这里插入图片描述

第一句话(关键点):int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
找出我们需要扩容的最大大小,这也就是为什么我们在开头的结论中规定每次只添加一个数据,如果一次性添加的数据数x大于集合大小的一半y/2,那么我们扩容后的大小就不是原来的1.5倍(y/2+y)了 而是x+y。
第二句话是检验集合容量是否很大,这里我们不做讨论。

本次的结果就是返回一个值,该值为现在集合容量的1.5倍。

然后我们使用ArrayscopyOf方法来实现集合的扩容,这里我提一下为什么要用copyOf方法,因为这样可以保证原来的数据还存在,如果创建一个新的对象的话,原来的数据就不存在了。后续就是一些赋值什么的操作啦。
以上就是我对于数组集合的一些理解,本人学艺不精如果有讲错的地方请指正!

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值