ArrayList中的addAll方法原来是这样的!

发布于:2022-08-02 ⋅ 阅读:(327) ⋅ 点赞:(0)

目录

第一步:校验索引

第二步:将目标集合转换成数组

第三步: 确保容量

第四步:两次拷贝

源码如下:

第一步:校验索引

rangeCheckForAdd(index)

 这一步的目的就是校验索引是否有效,若超出范围或者索引小于0,那么会抛出索引越界异常!

第二步:将目标集合转换成数组

其中numNew就是该数组的长度

第三步: 确保容量

 这一步主要是为了防止你的集合容量不够大,装不下要添加进来的集合,所以去判断容量是否足够大;

若容量满足,则按当前容量处理;若容量不够,且看下一步:grow(minCapacity)

 

很容易理解,首先,当进入扩容处理时,当前集合长度肯定是旧集合长度加上你将要添加进来的集合长度总长;

所以,集合默认先扩容一次:

int newCapacity = oldCapacity + (oldCapacity >> 1);

oldCaoacity = 旧集合长度;

newCapacity = 默认扩容长度;

 

若扩容一次还不满足,那么将你未来生成的集合长度minCapacity赋值给新的集合长度newCapacity;然后进行下一步判断:

 

 假如新的集合长度超过了集合的最大长度(Integer的最大值-8),那么新的集合长度将被赋值为Integer的最大值(2147483647);此外将集合复制到临时集合中,再复制回当前集合,那么当前集合的长度已经被改为了 newCapacity的长度;

第四步:两次拷贝

System.arraycopy(elementData, index, elementData, index + numNew,numMoved);

参数解释: elementData(第一个):源集合; index:源集合开始复制索引位置

                elementData(第二个):目标集合;index+numNew : 目标集合开始位置

                numMoved: 将要复制的个数

第一次拷贝,它是为了预留将要添加进来的集合的位置;

 第二次拷贝,它是添加 将要添加的集合到目标位置;

最后 集合的大小size += numNew!!!

操作就完成了!


网站公告

今日签到

点亮在社区的每一天
去签到