java arraylist_ArrayList底层数组扩容原理 - Java那些事儿

ArrayList部分一共五篇文章了,并且引入了时间复杂度来分析,强烈建议大家一定要按顺序阅读,相关文章分别是:

1、ArrayList初始化-Java那些事儿

2、ArrayList底层数组扩容原理 - Java那些事儿

3、时间复杂度 - Java那些事儿

4、三顾ArrayList - Java那些事儿

5、ArrayList的时间复杂度 - Java那些事儿

再次强调,ArrayList是一个普通的类,如果我们开心,可以自己写一个

ArrayList初始化-Java那些事儿 一文发表后,有人私信问我

7e8874c21e8cc43ee53d27e1fce6d4db.png

我们先回顾一下之前的所说过的数组,话不多说,上代码:

e92902afbfbcb399b23d2500a5184d5d.png

老规则,我们继续画一画,加深一下印象,上图:

dc8faf930c2006832eb82119fac25cd5.png

这个图我们去掉了 ArrayList初始化-Java那些事儿 一文图里那些无用的细节(方法区,常量池等),方便大家看起来清晰,我们用eclipse的debug功能看一下,看是否与我们图上画的一致

e3d415af5efeb89490c5c78dcdc2a172.png

再看一下执行结果,也在我们期望中

052af248bc6856fb25290a37de2e3de0.png

好,我们改一下代码,再往数组里加添加一个叫“周八”的person对象

7cc3875be4a6d0888e1f40c027fa5bc7.png

执行一下

35585744b20ed12a17976326b37c35a9.png

看到了传说的中数组下标越界异常。在Java中,数组一但在堆内存中创建,长度是固定的。

既然是固定的,那我们要往数组里加一个“周八”用户怎么办?没办法,只能重新new长一点的新的数组,把原来数组的元素复制过去,好吧,开始写代码吧,相信大家都会写

b3ee934bdd9c504136c0af27e33f6bae.png

把老数组的元素循环一下,赋值给新的数组,很简单也很清晰。debug看一下

b86adb448769a65a270cf258f416d53a.png

“周八”已经有了。以上代码虽然简单,但还不是最优雅的,老鸟一般会这么写,该段代码执行结果和上面那段代码一样

6a9fb4c226c16764842cbebcbcca2106.png

再画个图加深一下印象吧:

e60310c065e2ad1a069b455329b3334e.png

此图已用尽我洪荒之力,希望大家以后多想想对象在堆内存中的样子。不枉我一片苦心呀。
看到System.arraycopy()方法是不是似曾相识呢?我们在 ArrayList初始化-Java那些事儿 一文中提了一下,相信看到这里,大家都知道ArrayList里的底层数组扩容是怎么实现的了吧。在 ArrayList初始化-Java那些事儿 一文中,我们知道当ArrayList如果不指定构造个数的话,第一次往里面添加元素时底层数组会初始化一个长度为10的数组,我们再回顾一下昨天的源码,再来看一下ArrayList里的源码,当添加第11个元素时

9376bc012f4b7814fbaa88aa5d9eead5.png

再看grow()方法

9e9beaa6c3c3835661c90601277c7936.png

这儿有一段代码:int newCapacity = oldCapacity + (oldCapacity >> 1),>>是移位运算符,相当于int newCapacity = oldCapacity + (oldCapacity/2),但性能会好一些

018567938d826c10a057a3b67bc9a6a5.png

本文开始那个问题,到这儿就解决了,这就是数组的扩容,一般是oldCapacity + (oldCapacity >> 1),相当于扩容1.5倍

88fa9ee8379d29af0412bc83a2b5d4c8.png

我们再看一下源码,好简单:

3587e2b6e11e75987d2cb710eaae6d12.png

当我们在写代码过程中,如果我们大概知道元素的个数,比如一个班级大概有40-50人,我们优先考虑List list2 = new ArrayList<>(50)以指定个数的方式去构造,这样可以避免底层数组的多次拷贝,进而提高程序性能。

如果喜欢本系列文章,请为我点赞或顺手分享,您的支持是我继续下去的动力,您也可以在评论区留言想了解的内容,有机会本专栏会做讲解,最后别忘了关注一下我

上一篇: ArrayList初始化-Java那些事儿

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值