ArrayList集合扩容机制入门

首先,ArrayList集合存储的数据在底层是一个数组(名字elementData),这个数组是Object的数组,因为是Object数组,所以集合啥都可以装。

讲解ArrayList的扩容机制,要从ArrayList的构造器来分类,ArrayList有两种构造器,第一种是无参构造器,调用无参构造器创建的对象,在底层elementData数组是一个长度为0的空数组;第二种是有参构造,传入的是initialCapacity(初始的elementData数组的长度),调用这个构造器创建的对象在底层elementData数组的初始长度就是你传入的长度。

首先来演示调用无参构造的情况:

debug进入源码:

第一步:进入无参构造器

可以看到,无参构造将

DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给了elementData数组,那
DEFAULTCAPACITY_EMPTY_ELEMENTDATA是什么呢?

 

 再追进去看,可以看到

DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是一个长度为0的空数组,数组里面装的是Object的东西

 再来看看调用有参构造的情况:

追进 源码可以看到,首先进行判断你传进来的数据是不是大于0的,大于0就new一个长度为你传进来的数据(initialCapacity)的数组赋给elementData数组;

如果你传进来的数据是0,则将

EMPTY_ELEMENTDATA赋给elementData数组,那
EMPTY_ELEMENTDATA又是什么呢?在追源码,可以看到它是一个长度为0的数组

 如果你传进来的的数据小于0,那就会抛出一个异常

下面开始进入ArrayList集合的扩容:

第一种情况:用无参构造创建的对象,并且还没有对这个对象的数据进行操作,是首次对这个对象进行数据的操作

我们来add一个数据

 debug进入源码:

这里的size是一个int类型的数据,指的是elementData数组里面实际存在的元素的个数(不是数组的长度),比如我一个长度为10的数组,长度是在定义数组的时候就确定的,但是如果我一个数据都没存放,那size就是0,放一个进去,size就是1;

理解了size的意义,再来下一步,

进入

ensureCapacityInternal()这个函数

这个函数的参数minCapacity就是刚才的(size + 1),这个函数里面又调用了

ensureExplicitCapacity这个函数,
ensureExplicitCapacity这个函数的参数又是
calculateCapacity这个函数的返回值

 那我们先来看

calculateCapacity这个函数

这个函数先判断elementData数组是否是一个长度为0的数组,如果是,就返回

DEFAULT_CAPACITY(一个int型属性 等于 10)和minCapacity之中的最大的那个,其实永远也只会返回DEFAULT_CAPACITY,因为当elementData长度为0时,这个数组的size不就是0吗,minCapacity就是传进来的size+ 1 = 1,不永远小于DEFAULT_CAPACITY吗?

 好,现在

ensureExplicitCapacity函数接收到了10这个形参

进入这个函数,minCapacity就是传入的10,

modCount++不用管,它与扩容无关

下一步

判断minCapacity(10)是否大于elementData这个数组的长度,此时这个数组是长度为0的数组,

那当然满足这个条件,进入grow函数,grow函数才就是真正的给elementData数组扩容的函数,

grow函数比较复杂,但功能很简单,(1).如果elementData数组是长度为0的数组(也就是用无参构造创建的对象),就将elementData扩容至长度为10   (2).elementData数组长度不为0(给elementData数组已经装满了,要想再装数据就得扩容),此时的elementData数组就会扩容至原elementData数组长度的1.5倍

附加说明:

其实这个函数的if()里面的语句作用就是用来给无参构造创建的对象的elementData数组进行初始化的,初始化长度为10,也就是说,只要是使用无参构造创建的对象,elementData数组的长度都是10,使用有参构造创建的对象的elementData数组的长度就是你指定的长度(0除外,0是10)

 每次进行调用add进行数据的添加,都会进行判断elementData数组的长度还够不够加进去1个数据,如果不够就会进行1.5被的扩容,再将数据加入到elementData数组中,同时size++;

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值