java 数组实现原理_java ArrayList实现原理

java ArrayList实现原理

ArrayList底层源码分析

ArrayList:底层的数据结构是数组,作为List的主要实现类;线程不安全,效率高。

ArrayList底层实际上是一个动态的数组,与普通的数组相比较,它的容量可以根据需要动态地增长。ArrayList 继承了AbstractList,实现了List,它是一个具有增删改查功能的数组。

ArrayList中元素一旦超出了底层数组的长度,就需要扩容,默认是扩容为之前的1.5倍,同时,将原来数组的内容复制到新的数组中。

ArrayList的构造器源码,实现了三个接口

abd3ec5625fa3bb40450191bb77a7bd2.png

ArrayList实现了RandmoAccess接口,即提供了随机访问的功能,RandmoAccess是java中用来被list实现,为其提供随机访问功能的。我们可以通过元素的序号来快速地获取元素对象,这就是快速随机访问。

ArrayList实现了Cloneable接口,可以被克隆。

ArrayList 实现java.io.Serializable接口,ArrayList支持序列化,能通过序列化去传输到文件流中

ArrayList的结构:

f7fda298be4840a18d920efc2a4cf667.png

来看看arrayList的部分源码,

ArrayList的有参方法,设置默认长度

4033c380d177891e4035ae4eec620630.png

这里的参数initialCapacity是设置ArrayList的默认长度,当initialCapacity大于0的时候就new一个新的长度为initialCapacity的数组,等于0就创建一个空的数组,其它情况下就抛出异常。比如说,List list = new ArrayList(85);就会new一个新的长度为85的数组。

ArrayList的无参方法

c62cc7464cd0ff8ba316fc1ad8c6dbd0.png

fccf32eb9f6930011b9301d109d1a2dc.png

如果调用ArrayList的无参方法,就会生成一个空的数组,长度为0。

ArrayList的add方法

df610feb8153e1559dcb4adcc7647b7e.png

1)通过源码可以知道,add方法添加元素后,会调用ensureCapacityInternal()方法,该方法又调用了ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

baadf37bc5449d0594531753adfd4940.png

2)ensureCapacityInternal方法中,判断了当前数组是否为空,如果为空则取minCapacity 为 默认容量和参数 minCapacity 之间的最大值,不为空的话,则调用了ensureExplicitCapacity方法

cdee580baaae12836e05c1ebacb09957.png

3)ensureExplicitCapacity方法中,modCount是修改该数组的统计次数,该变量用来实现fail-fast机制,后面的if语句主要防止溢出,确保指定的最小容量 > 数组缓冲区当前的长度,之后执行grow方法

cd4ca4c60d4564fa120796c80be986a9.png

4)grow方法主要是防止溢出,扩大容量的。

int newCapacity = oldCapacity + (oldCapacity >> 1);将新的容量大小定为旧容量大小的1.5倍

if (newCapacity - minCapacity < 0) newCapacity = minCapacity;如果新容量仍然小于所需指定的最小长度,那么就把所定义的最小长度赋值给新容量

if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);如果新的容量大小大于最大储存容量,则调用hugeCapacity方法进行大容量分配

503e09031943ac68b4d2c52e0d22f88f.png

最后用copyOf方法把原来的数组复制到新的容量更大的数组中去

ArrayList总结:

1)ArrayList底层是由容量可变化的数组来实现的

2)在jdk1.7中创建ArrayList数组是先创建一个长度为10的数组,在jdk1.8中是等list对象调用add()方法的时候,再创建长度为10的数组

3)一旦添加的元素超出底层数组长度,会将数组原来的容量默认扩容为1.5倍,同时,将原有数组的元素复制到新的数组中去

4)如果要储存指定数量的对象到ArrayList数组中去,可以直接List list = new ArrayList(n);(n为对象数量),在方法写上长度,这样就可以直接创建该长度的底层数组,避免了数组的重复扩容,提高了效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值