源码——ArrayList(JDK 1.8)
1. 属性
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//序列化id
private static final long serialVersionUID = 8683452581122892189L;
//默认初始化容量为10
private static final int DEFAULT_CAPACITY = 10;
//指定容量为0时,返回该数组
private static final Object[] EMPTY_ELEMENTDATA = {
};
/*
调用无参构造返回该数组。
它与EMPTY_ELEMENTDATA的区别就是:该数组是默认返回的,而EMPTY_ELEMENTDATA是在用户指定容量为0时返回。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
/*
保存添加到ArrayList中的元素。
ArrayList的容量就是该数组的长度。
该值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,当第一次添加元素进入ArrayList中时,数组将扩容值DEFAULT_CAPACITY。
被标记为transient,在对象被序列化的时候不会被序列化。
*/
transient Object[] elementData; // non-private to simplify nested class access
//ArrayList的实际大小(数组包含的元素个数/实际数据的数量)默认为0
private int size;
/*
分派给arraylist的最大容量
为什么要减去8呢?
因为某些VM会在数组中保留一些头字,尝试分配这个最大存储容量,可能会导致array容量大于VM的limit,最终导致OutOfMemoryError。
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
}
2. 构造方法
/*
构造一个初始容量为10的空列表
我们知道DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空的Object[],将elementData初始化,elementData也是个Object[]类型。空的Object[]会给默认容量10。但是这里我们并没有看到数组的容量变为10啊,那么什么时候会被初始化为10的数组呢?答案是有元素被加入时(add方法).当进行第一次add的时候,elementData将会变成默认的长度:10。
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/*
ArrayList(int initialCapacity):构造一个指定容量为capacity的空ArrayList。这是一个带初始容量大小的有参构造函数。
初始容量大于0,实例化数组,将自定义的容量大小当成初始化elementData的大小
初始容量等于0,将EMPTY_ELEMENTDATA赋给elementData
初始容量小于0,抛异常
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
总结:ArrayList的构造方法就做一件事情:初始化数组,也即elementData。
3. 重点方法
3.1 get()
//获取指定下标位置的元素
public E get(int index) {
rangeCheck(index); //越界检查
return elementData(index); //返回指定位置的元素
}
//越界检查
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//返回对应下标位置的元素
E elementData(int index) {
return (E) elementData[index];
}
3.2 set()
//修改元素
public E set(int index, E element) {
rangeCheck(index); //越界检查
E oldValue = elementData(index); //记录旧值
elementData[index] = element; //新值替换旧值
return oldValue; //返回旧值
}
3.3 add()
//添加元素至数组的末尾
public boolean add(E e)