ArrayList扩容小结

ArrayList小结

首先ArrayList是我们List接口的一个实现类,是线性非安全的。优点是访问数据快,复杂度为O(1),缺点是对数据进行删除和添加的话不方便,时间复杂度在最好的情况下为O(1),最坏的情况下为O(n)。 那么接下来我们就来看看ArrayList在jdk中是如何实现的:

在这里插入图片描述

第一个参数是10,是ArrayList在加入元素时会进行,扩容的长度。然后是两个默认的空数组。接下来我们就可以来看一下ArrayList的初始化,以及它是如何进行元素的添加和扩容的。

在这里插入图片描述
首先是两个构造方法,分别是带参数的构造方法和不带参数的构造方法。我们可以看到,如果我们在构造ArrayList的时候如果一开始就带了参数那么如果参数大于0的情况下我们会为它创建长度为参数大小的数组,否则我们按照默认的空数组进行创建。

在这里插入图片描述
来到add方法,首先我们将size进行一个加一,因为我们我们是新加入了一个元素,然后调用我们的ensureCapacityInternal方法判断我们现在的存储空间是否是够用的,然后我们进行一个赋值操作。

在这里插入图片描述
在这里我们可以看到我们将现在的size和我们的初始默认参数进行了一个比较,并且取了他们当中的最大值。(即当我们加入1个元素时,此时的minCapacity为1,而Default参数为10)
所以此时我们的minCapacity已经变成了10,然后我们进入到ensureExplicitCapacity方法中进行判断。
在这里插入图片描述
我们可以轻松地看出我们的if是成立的,因为minCapacity是10,而此时的elementData的长度是0.所以我们可以继续向下进入到,grow方法中进行扩容。
在这里插入图片描述
在这个方法中我们可以看到我们的ArrayList是怎样进行扩容的了,首先我们将长度定义为之前的长度加上之前的长度右移两位之后得到的树(并不是完全意义上的1.5倍,但是近似)。然后我们判断当前扩容之后的长度是否够用,否则我们就以传入的长度(我的理解此时数据的多少)作为数组长度,因为这是我们一开始取了max之后的长度。例如在addAll() 方法中我们可以看出

在这里插入图片描述
此时的size是加上了我们要加入的所有元素的长度的。所以我们在前面得到的size+1则是我们此时数据的真实长度,所以我们如果使用此方法,我们的扩容就可能跟不上我们的1.5倍扩容机制,所以我们才有了不够的情况下使用真实长度作为数组长度的情况。而最后的实现才用的是Arrays.copyOf方法,此方法区别于下面的System.arraycopy的方式,此方法是在原数组的基础上进行长度的改变,如一开始我们的数组nums1,2,3 如果我们使用了Arrays.copyOf(nums,5) 此时数组则变为了1,2,3,0,0
ArrayList中还有在index添加元素的add方法,此时我们主要利用的是System.arraycopy的方式进行实现,此方法主要是在两个数组上进行实现,方法的参数分别是源数组,开始复制的下标,目标数组,开始的下标,要复制的长度最后的结果是存在目标数组当中的
类似的实现方式还有remove操作

在这里插入图片描述
以上就是对ArrayList的一些思考总结,欢迎批评指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值