1、前言
对于平常开发的时候遇到的数组列表,在此做一个简单的源码阅读记录,JDK1.8版本。
2、ArrayList的类关系
首先看下数组列表的类关系图,可以看到实现了
可序列化接口,支持序列化与反序列化;可克隆的接口,可以被克隆;随机访问接口,支持随机访问,另外fori循环会比迭代器循环效率高,代码如下:for (int i=0,n=list。size();I n;(一)
名单。得到(我);比这个循环运行得更快:
for(迭代器I=列表。迭代器();I . has next();)
I . next();
3、ArrayList的源码
一、类的属性
/*** 默认初始容量
*/
私有静态最终int DEFAULT _ CAPACITY=10
/**
* (用于空实例的)共享空数组实例
*/
私有静态最终对象[]EMPTY _ element数据={ };
/**
* (用于默认大小的空实例的)共享空数组实例,我们将其与空的元素数据区分开来,
* 以了解何时添加第一个元素。
*/
私有静态最终对象[]DEFAULT capacity _ EMPTY _ element数据={ };
/**
* 存储数组列表元素的数组缓冲区数组列表。的容量是此数组缓冲区的长度。任何
*元素数据==DEFAULTCAPACITY _ EMPTY _ element数据元素数据
* 将在添加第一个元素时扩展到默认容量(10)。
*/
瞬态对象[]元素数据;//瞬态关键字标记的成员变量不参与序列化过程
/**
*数组列表的大小(包含的元素数)
*/
私有(同Internationalorganizations)国际组织大小;
/**
* 可分配的数组的最大大小,可能会导致离开记忆错误:请求的阵列大小超过虚拟机限制
*/
私有静态最终int MAX_ARRAY_SIZE=整数MAX _ VALUE-8;
二、add()方法
//默认往数组末尾添加元素公共布尔加法
保证容量内部(大小为1);//大小加一
元素数据[大小]=e;
返回真;
}
private void ensurecapacityneral(int minCapacity){//minCapacity=size 1
//elementData是成员变量
ensureExplicitCapacity(计算容量(元素数据,最小容量));
}
私有静态int calculateCapacity(对象[] elementData,int minCapacity) {/如果
if(元素数据==DEFAULT capacity _ EMPTY _元素数据){ 0
//数组为空时,返回较大的数
返回数学最大值(默认容量,最小容量);
}
返回minCapacity//数组非空时,返回最小容量=1号
}
private void ensureExplicitCapacity(int minCapacity){//minCapacity=size 1
modCount//计数
//数组元素个数加一之后如果大于当前数组长度,则进行扩容
if(MinCapacity-ElEMENTDATa。长度0)
增长(最小容量);
}
私有void grow(int minCapacity){//minCapacity=size 1
int oldCapacity=elementDa
ta.length; // 旧数组的长度 int newCapacity = oldCapacity + (oldCapacity >> 1); // 新数组的长度 = 1.5倍旧数组长度 // 新数组长度小于数组元素个数加1 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; // 新数组长度大于数组最大值 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 创建一个新的数组,并把旧数组元素复制过去,newCapacity为新数组大小 elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // 新数组长度大于数组最大值,并且minCapacity<0才会抛出oom错误 throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } // 指定位置添加元素 public void add(int index, E element) { // 下标合法性校验 rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // 生成一个index位置为null的新数组 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }