简介
ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可以称之为动态数组。
ArrayList实现了List,RandomAccess,Cloneable,java.io.Serializable等接口。
ArrayList实现了List,提供了基础的添加、删除、遍历等操作。
ArrayList实现了RandomAccess,提供了随机访问的能力。
ArrayList实现了Cloneable,可以被克隆。
ArrayList实现了Serializable,可以被序列化。
源码解析
属性
/**
*默认容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
*空数组,如果传入的容量为0时使用
*/
private static final Object[] EMPTY_ELEMENTDATA = {
}
/**
*空数组,传入容量时使用,添加第一个元素的时候会重新初始化为默认容量大小
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
/**
*存储元素的数组
*/
transient Object[] elementData;
/**
*集合中元素的个数
*/
private int size;
(1)DEFAULT_CAPACITY
- 默认容量为10,也就是通过new ArrayList()创建时的默认容量。
(2)EMPTY_ELEMENTDATA
- 空的数组,这种是通过new ArrayList(0)创建时用的是这个空数组。
(3)DEFAULTCAPACITY_EMPTY_ELEMENTDATA
- 也是空数组,这种是通过new
ArrayList()创建时用的是这个空数组,与EMPTY_ELEMENTDATA的区别是在添加第一个元素时使用这个空数组的会初始化为DEFAULT_CAPACITY(10)个元素。
(4)elementData
-
真正存放元素的地方,使用transient是为了不序列化这个字段。
-
至于没有使用private修饰,后面注释是写"为了简化嵌套类的访问",但是个人觉得加了private嵌套类一样可以访问。
-
private表示是类私有的属性,只要是在这个类内部都可以访问,嵌套类或者内部类也是在类的内部,所有也可以访问类的私有成员。
(5)size
- 真正存储元素的个数,而不是elementData数组的长度
ArrayList(int initialCapacity)构造方法
传入初始容量,如果大于0就初始化elementData为对应大小,如果等于0就使用EMPTY_ELEMENTDATA空数组,如果小于0抛出异常。
public ArrayList(int initialCapacity){
if (initialCapacity > 0) {
//如果传入的初始化容量大于0,就创建一个数组存储元素
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//如果传入的初始容量等于0,使用空数组EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
}
}
ArrayList()构造方法
不传初始容量,初始化为DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组,会在添加第一个元素的时候扩容为默认大小,即10
public ArrayList() {
//如果没有传入初始容量,则使用空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA
//使用这个数组是在添加第一个元素的时候会扩容到默认大小10
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
ArrayList(Collection c)构造方法
传入集合并初始化elementData,这里会使用拷贝把传入集合的元素拷贝到elementData数组中,如果元素的个数为0,则初始化为EMPTY_ELEMENTDATA空数组。
public ArrayList(Collection<? extends E> c) {
//集合转数组
elementData = c.toArray();
if ((size = elementData