从访谈的角度分析ArrayList源代码

注意:本系列文章中使用的jdk版本都是java8。

ArrayList类图如下:ArrayList的底层由一个数组实现,该数组的特征是固定大小,而ArrayList实现动态扩展。

ArrayList的一些变量如下,将在以下分析中使用。

/ ** *默认容量* / private静态最终int DEFAULT_CAPACITY = 10; / ** *空对象数组* / private静态最终Object [] EMPTY_ELEMENTDATA = {}; / ** *无参数构造函数创建的空数组* / private静态最终Object [] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; / ** *缓存存储数据的数组的变量* / transient Object [] elementData; / ***元素数* / private int大小;初始化ArrayList并初始化ArrayList通常使用以下两个构造函数1.1使用无参数构造函数初始化ArrayList时,如果不指定大小,则将创建一个空数组。

public ArrayList(){this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;} 1.2指定数组大小的构造函数将创建一个估计大小的数组。

指定大小后,仅指定数组初始值的大小,这不会影响后续的扩展。

指定的优点是它可以节省内存和时间开销。

公共ArrayList(int initialCapacity){if(initialCapacity> 0){this.elementData =新对象[initialCapacity];} else if(initialCapacity == 0){this.elementData = EMPTY_ELEMENTDATA;} else {引发新的IllegalArgumentException(“ Illegal容量:“ + initialCapacity);两个添加元素,动态扩展ArrayList.add(E e)源代码:public boolean add(E e){sureCapacityInternal(size + 1); //递增modCount !! elementData [size ++] = e;返回true;} add()中的elementData [size ++] = e很容易理解,即将元素插入size位置,然后插入size ++。

让我们专注于sureCapacityInternal(size + 1)方法;私用void sureCapacityInternal(int minCapacity){If(elementData = = DEFAULTCAPACITY_EMPTY_ELEMENTDATA){minCapacity = Math.max(DEFAULT_CAPACITY,minCapacity);如果(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)是首次确定sureExplicitCapacity(ensureExplicitCapacity)变量(ensureExplicitCapacity)(ensureDataCapacity)中的缓存是否与判断内部变量(ensureDataCapacity)是否添加元素相同。

如果是第一次添加元素,请将初始大小设置为默认容量10,否则为传入参数。

此方法的目的是获得初始阵列容量。

获得初始容量后,请调用suresureExplicitCapacity(minCapacity)方法;私有void sureExplicitCapacity(int minCapacity){modCount ++; //具有溢出意识的代码If(minCapacity)-elementData.length> ExplicitCapacity(0)容量方法;要确定是否需要扩展,如果是第一次添加元素,minCapacity为10,elementData容量为0,则需要扩展。

调用grow(minCapacity)方法。

//数组的最大容量private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8; private void grow(int minCapacity){意识溢出的代码= int oldCapacity = elementData.length的原始长度的1.5倍;数组原始长度的1.5倍int newCapacity = oldCapacity +(oldCapacity>> 1); //如果扩展容量小于需要扩展的长度,则如果(newCapacity-minCapacity 0)-minCapacity /数组的最大容量大于容量minCapacity,则使用需要扩展的容量使用最大整数如果(newCapacity- MAX_ARRAY_SIZE> 0)NewCapacity = hugeCapacity(minCapacity); // minCapacity通常接近大小,则长度是一个双数:soCapacity ofCapacity(newCapacity)grow(Capacity))扩展数组的方法,扩展大小为1.5倍于原始数组,如果计算出的扩展容量小于所需容量,则扩展大小为所需容量,如果扩展容量大于阵列的最大容量,则调用hugeCapacity(minCapacity)方法,展开将数组设置为最大整数长度,然后将elemetData数组指向新扩展的内存空间,然后将元素复制到新空间。

当所需的收集容量特别大时,扩展1.5倍会占用大量空间,因此建议在初始化期间估计容量大小。

三个删除元素ArrayList提供了两种删除元素的方法,可以按索引和元素删除。

这两个删除是相似的。

删除元素后,以下元素将一次向前移动。

ArrayList.remove(int index)源代码:public E remove(int index){rangeCheck(index); modCount ++; E oldValue = elementData(index); Int numMoved = size-index-1;