《ArrayList扩容方式的理解》

从两个方面进行理解:

1.1、内部数组elementDate是咋样进行初始化的,初始化的长度是多少,这样才能知道什么时候容量不够用,要进行扩容了。

初始化数组是建立在两个构造方法上的:无参构造和有参构造。

1.1.1、无参构造方法:将当前的内部数组初始化为一个长度为0的空数组

让elementDate这个数组指向一个常量

faf1c28ffa474503a20472f7aba5f073.png

这个常量定义为一个Object类型的空数组

2df2c49f6f6646beabb4c3a5c0479f59.png

1.1.2、有参构造方法:按照指定容量initialCapacity进行数组初始化

当传入一个指定的初始化容量200时

5c8e8c6a2ece40b4a771da8669c70e33.png

 先进行判断,如果容量大于0,会按照初始化容量来创建elementData数组,如果容量等于0,就就让elementData数组初始化为一个空数组,如果容量小于0(负数),就会抛异常。

093427139fae4e84a80c0ee65ac6c126.png

 如果我们能预估当前我们要操作的数据的规模,那么就能一次性把数据添加到位,这样至少在添加前两百个元素时,内部数组是不会产生扩容。

因为空数组是不能存数据的,所以要进行扩容

1.2、扩容分两种情况:

1.2.1、当第一次添加元素时,数组扩容为10

用无参构造方法创建出一个空数组时,当我们向数组中添加第一个元素会调用add()方法,add()方法会将当前我们要添加的元素传进来。

09baababdfcb40f4b14ef1674146b44f.png

而add()方法中会执行两个逻辑,一个是确保内部容量够用,二是将元素放进elementDate数组中。

但当前是一个空数组,所以我们进行扩容。

调用ensureCapacityInternal()方法,它的参数为size+1(size是当前数组的元素个数,+1是往数组中添加一个元素),用参数size+1来判断当前数组的容量。

d7bcfbb468a14e88a3ecd28d7d5ed56e.png

这个方法中又调用calculateCapacity()方法,这个方法是用来计算容量和所需要的最小容量minCapacity。

8a48007a4db24cc8a827ca4a2b908e9a.png

 在calculateCapacity()方法中,先判断elementDate数组是否为一个空数组,如果是一个空数组,就会返回DEFAULT_CAPACITYminCapacity当中的最大值。

be4e637c6420483fb2668cecffcc7470.png

DEFAULT_CAPACITY:是一个常量,值为10。而minCapacit是传进来的参数,就是上面提到的size+1,值为1(数组为空,所以size为0,添加一个元素后,minCapacity就为1)

8be5042f98c64b4aa6127866e9b783f4.png

1<10,所以返回的minCapacity的值为10。

计算出来的minCapacity回传给ensureExplicitCapacity()方法,这个方法中如果minCapacity的值大于当前数组的长度,那就会以minCapacity的值10进行扩容。

390567de21c747e2a88a5654b177a3ca.png

 1.2.2、当数组容量不足时,按照原来容量的1.5倍进行扩容增长

当我们向数组添加第十一个元素时,现有的size长度为10,所以传进去的参数为11,调用ensureCapacityInternal()方法。

884cf6ca08f447d484875af8d003548a.png

 因为现在不是一个空数组了,所以直接将参数11传给ensureExplicitCapacity()方法。cb72da1acbea490fa88b00cb5003fab6.png

这个方法中会判断所需的最小容量减当前数组长度是否大于0,因为11-10>0,所以调用grow()方法。定义oldCapacity代表原来的容量,当知道原来的容量时,就可以在原来容量的基础上加上原来容量向右移一位(相当于除以2的一次方)。

ba3334d6e9d949a6b14eacd47617b10a.png

int newCapacity = oldCapacity + (oldCapacity >> 1)  理解为:在原来容量的基础上再加上原来容量的一半,(就是原来容量的1.5倍)。

把 elementData数组中的元素复制到新的数组里,复制的个数是新容量的个数,所以新数组的长度就为15。既完成了数组的扩容,又把原来数组中的元素复制到新的数组中。

33070c2d61c74fd2a8fad08265758768.png

在扩容时,秉持的一个思想是:要尽量减少扩容的频率。

  • 21
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值