java ArrayList实现原理

java ArrayList实现原理

ArrayList底层源码分析
ArrayList:底层的数据结构是数组,作为List的主要实现类;线程不安全,效率高。
ArrayList底层实际上是一个动态的数组,与普通的数组相比较,它的容量可以根据需要动态地增长。ArrayList 继承了AbstractList,实现了List,它是一个具有增删改查功能的数组。
ArrayList中元素一旦超出了底层数组的长度,就需要扩容,默认是扩容为之前的1.5倍,同时,将原来数组的内容复制到新的数组中。

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

  1. ArrayList实现了RandmoAccess接口,即提供了随机访问的功能,RandmoAccess是java中用来被list实现,为其提供随机访问功能的。我们可以通过元素的序号来快速地获取元素对象,这就是快速随机访问。
  2. ArrayList实现了Cloneable接口,可以被克隆。
  3. ArrayList 实现java.io.Serializable接口,ArrayList支持序列化,能通过序列化去传输到文件流中

ArrayList的结构:

来看看arrayList的部分源码,

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

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

ArrayList的无参方法


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

ArrayList的add方法

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

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

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

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方法进行大容量分配

最后用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为对象数量),在方法写上长度,这样就可以直接创建该长度的底层数组,避免了数组的重复扩容,提高了效率。

posted @ 2020-08-18 22:06  TidalCoast  阅读(289)  评论(0编辑  收藏  举报