ArrayList的底层是数组。继承了AbstractList抽象类,实现了List、RandomAccess、Cloneable、java.io.Serializable接口。其中RandomAccess接口是标记接口,用来表明其支持快速的随机访问。属于RandomAccess的实现(如ArrayList)还是SequenceAccess的实现(如LinkedList)需要进行区分开来,因为他们的遍历算法效率差别很大。ArrayList使用索引值(get方法)去访问速度很快,使用迭代器则相对较慢。而LinkedList则相反。
//实现了List, RandomAccess, Cloneable, java.io.Serializable。支持快速随机访问、克隆、可序列化、非线程安全 JDK1.7 java.util
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;//版本序列号
private static final int DEFAULT_CAPACITY = 10;//初始容量大小
private static final Object[] EMPTY_ELEMENTDATA = {};//空数组实例,指定容量为0时的初始化
private transient Object[] elementData;底层数组,transient表明不进行序列化
private int size;//实际元素个数
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];//初始化底层数组
}
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;//不指定容量时为空数组,容量为10
}
//构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection的迭代器返回它们的顺序排列的。
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
//elementData.getClass()有可能不等于Object[].class,文档中说此处是一处bug,所以加了这个判断
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
//将当前容量值设为等于实际元素个数
public void trimToSize() {
modCount++;//修改次数加1
if (size < elementData.length) {//实际元素个数小于数组的长度
elementData = Arrays.copyOf(elementData, size);//深复制
}
}
public void ensureCapacity(int minCapacity) {//增加此 ArrayList实例的容量
int minExpand = (elementData != EMPTY_ELEMENTDATA)? 0 : DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//传入值与默认值中的较大值
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//修改次数增加
if (minCapacity - elementData.length > 0)//最小空间是否比现在的数组长度大
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//原来的1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;//不够就将数组长度设置为需要的长度
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);//复制生成数组,开辟新的内存空间
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
public int size() {//容器中元素的个数
return size;
}
public boolean isEmpty() {//是否有元素
return size == 0;
}
public boolean contains(Object o) {//是否包含该元素
return indexOf(o) >= 0;
}
public int indexOf(Object o) {//返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1
if (o == null) {//判断null
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {//不为null
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;//没有则返回-1
}
public int lastIndexOf(Object o) {//最后一次出现的索引
if (o == null) {
for (int i = size-1; i >= 0; i--)//反向循环
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;//没有则返回-1
}
public Object clone() {//克隆函数,浅复制(浅克隆)
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
public Object[] toArray() {//转化为数组。浅复制
return Arrays.copyOf(elementData, size);
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {//转化为数组,保留具体类型。浅复制
if (a.length < size)//size较大时
return (T[]) Arrays.copyOf(elementData, size, a.getClass());//返回size大小长度的数组
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)//length较大时
a[size] = null;//仅接着的尾部元素设为null,再之后的元素不变
return a;
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];//直接返回数组的index处的元素
}
public E get(int index) {//返回元素
rangeCheck(index);//校验
return elementData(index);
}
public E set(int index, E element) {//设置元素
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;//返回原来的元素
}
public boolean add(E e) {//新增元素
ensureCapacityInternal(size + 1); //扩容,修改次数会加1
elementData[size++] = e;//增加元素,然后size自增
return true;
}
public void add(int index, E element) {
rangeCheckForAdd(index);//校验
ensureCapacityInternal(size + 1); // 扩容,修改次数会加1
System.arraycopy(elementData, index, elementData, index + 1,
size - index);//把数组从index开始复制到从index+1开始
elementData[index] = element;//index位放置新元素
size++;
}
public E remove(int index) {//根据索引移除
rangeCheck(index);//校验
modCount++;//修改次数加1
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)//此时index不为末尾
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; //清空最后一位方便GC回收
return oldValue;//返回原来的值
}
public boolean remove(Object o) {//移除此列表中首次出现的指定元素
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++;//操作次数加1
int numMoved = size - index - 1;
if (numMoved > 0)//此时index不为末尾
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; //清空最后一位方便GC回收
}
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {//清空元素,size为0
modCount++;//修改次数自增
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
public boolean addAll(Collection<? extends E> c) {//在尾部增加所有元素
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // 扩容,修改次数会加1
System.arraycopy(a, 0, elementData, size, numNew);//在尾部增加数组中的元素
size += numNew;
return numNew != 0;
}
public boolean addAll(int index, Collection<? extends E> c) {//在指定位置增加所有元素
rangeCheckForAdd(index);//校验
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // 扩容,修改次数会加1
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
protected void removeRange(int fromIndex, int toIndex) {//移除从fromIndex(包括)到toIndex(不包括)之间的元素
modCount++;//操作次数加1
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;//赋值为null,方便GC回收
}
size = newSize;
}
private void rangeCheck(int index) {//参数校验
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {//参数校验
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {//封装异常信息
return "Index: "+index+", Size: "+size;
}
public boolean removeAll(Collection<?> c) {//移除集合中的元素
return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c) {//移除非集合中的元素
return batchRemove(c, true);
}
//求差集/补集
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];//如果elementData[r]满足要求,则留下,继续遍历
} finally {
//抛出异常时
if (r != size) {//没遍历完
//将r后面的元素直接拷贝到w后面来
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;//元素个数增加size-r
}
if (w != size) {//有多余元素时设成null,方便回收
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;//重新赋值元素个数
modified = true;
}
}
return modified;
}
//序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
int expectedModCount = modCount;
s.defaultWriteObject();
s.writeInt(size);//写入数组容量
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);//写入每个元素
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
//反序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
s.defaultReadObject();
s.readInt(); // ignored
if (size > 0) {
ensureCapacityInternal(size);
Object[] a = elementData;
//读出值
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
public ListIterator<E> listIterator(int index) {//双向迭代器,从index开始迭代
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
public ListIterator<E> listIterator() {//双向迭代器,从起始开始迭代
return new ListItr(0);
}
public Iterator<E> iterator() {//迭代器
return new Itr();
}
//迭代器的实现(详细见上一篇AbstractList中源码分析)
private class Itr implements Iterator<E> {
int cursor; // 下一个元素的索引
int lastRet = -1; // 上一个元素的索引
int expectedModCount = modCount;//期望修改次数=实际修改次数,初始值为0
public boolean hasNext() {//是否还可以进行迭代
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//双向迭代器的实现(详细见上一篇AbstractList中源码分析)
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
//截取其中的一部分元素构建新的列表(详细见上一篇AbstractList中的subList)
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
//SubList内部实现(详细见上一篇AbstractList中的subList)
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
public boolean addAll(Collection<? extends E> c) {
return addAll(this.size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public boolean hasPrevious() {
return cursor != 0;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
}
}