问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

ArrayList的扩容原理(详细带代码讲解)

创作时间:
作者:
@小白创作中心

ArrayList的扩容原理(详细带代码讲解)

引用
CSDN
1.
https://blog.csdn.net/m0_71572133/article/details/144173562

ArrayList是Java中最常用的集合之一,其扩容机制直接影响着程序的性能。本文将通过源码分析,详细讲解ArrayList的扩容原理,帮助读者深入理解这一重要数据结构的内部实现。

ArrayList的源码

ArrayList的底层是Object类型的数组,下面我们先来看一下ArrayLIst的源码:

这里调用ArrayList的无参构造方法,将这个被final修饰的名为“DEFAULTCAPACITY_EMPTY_ELEMENTDATA”的空数组赋值给底层创建的名为elementDate的数组。可见现在elementDate当前为空。

第一次添加元素时

第一次添加元素时,调用了ensureCapacityInternal方法,里面是size+1,由下图可知size是默认值0,所以ensureCapacityInternal方法参数为1,接下来进入此方法。

我们可以得知minCapacity的值为1,先调用calculateCapacity方法传入的值分别为elelmentData和minCapacity,由上文可知它们的值分别为0和1。

进入calculateCapacity方法:我们已知elementData与 DEFAULTCAPACITY_EMPTY_ELEMENTDATA的值都为0,所以if条件判断语句成立,返回的是DEFAULT_CAPACITY和minCapacity中间的最大值。下图系统给出DEFAULT_CAPACITY的值为10,所以我们返回的值为10。

接下来进入ensureExplicitCapacity方法modCount的默认值为0,进行++操作之后值为1;if条件判断minCapacity为1,elementData.lenght为0,进入grow方法。

参数为minCapacity 0,将数组长度赋值给oldCapacity所以旧容量的值为0,新容量的值是旧容量加上旧容量右移一位的值,也就是旧容量的1.5倍。所以新容量是0,接下来条件判断,满足第一个if条件 新容量被1赋值,第二个if判断不满足,则进入复制数组环节,elementData长度为1并将元素传进去调用copyOf方法。

返回值是一个泛型类型的数组,长度为新容量的长度,得到一个数组接下来依次返回原调用处。

当数组添加元素长度超过10之后,在grow方法处正常情况下有两种扩容方法:

第一种:新容量等于旧容量的1.5倍,如果足够用则继续接下来的复制。

第二中:也就是当扩容到1.5倍还是不够用的时候,则会直接扩容到需要的大小。

简单来说,在正常情况下ArrayList的扩容机制为:

  1. 创建ArrayList对象:内部数组elementDate被初始化成一个空数组;
  2. 当往集合中添加第一个元素时,数组初始化容量为10;
  3. 已经添加了10个元素,容量不足,扩容为原数组的1.5倍;
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号