1. 类的定义
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
从定义中可以看出
- ArrayList是一个泛型类
- ArrayList继承了AbstractList抽象类
- ArrayList实现了List接口
- ArrayList实现了RandomAccess接口,表示ArrayList支持随机访问,实质就是ArrayList是一个Object类型的数组,无法创建泛型数组
- ArrayList实现了Cloneable接口,表示ArrayList支持克隆
- ArrayList实现了java.io.Serializable接口,表示ArrayList支持序列化

2.字段属性
//序列化版本号
private static final long serialVersionUID = 8683452581122892189L;
//默认容量为10
private static final int DEFAULT_CAPACITY = 10;
//容量为0的时候的默认空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//初始化时默认空数组,因为有可能不存放元素
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//真正存储数据的地方, 当第一次添加数据的时候容量会扩容到DEFAULT_CAPACITY(10)
//transient修饰表示序列化会被忽略
transient Object[] elementData; // non-private to simplify nested class access
//有效数据的长度,不一定等于elementData的长度
private int size;
//最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//修改次数,从父类继承来的
protected transient int modCount = 0;
3.构造函数
//指定容量的构造函数
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//如果指定容量大于0,则创建指定容量大小的数组
//注意数组类型不是泛型,而是Object,无法创建泛型数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//如果指定容量为0,则使用默认的EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
} else {
//容量小于0抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//不带参数的构造函数,默认使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA初始化
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//传入一个集合作为参数的构造函数
public ArrayList(Collection<? extends E> c) {
//把集合内容转换为数组赋值给elementData
elementData = c.toArray();
//给size赋值
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
//如果传入的集合不是Object类型需要强转后再拷贝得到新的数组再赋值给elementData
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
//如果长度为0则把EMPTY_ELEMENTDATA赋值给elementData
this.elementData = EMPTY_ELEMENTDATA;
}
}
从上面可以看出
- 可以传入一个int类型的容量来初始化一个ArrayList
- ArrayList有默认不带参数的构造函数
- 可以传入一个Collection对象来初始化一个ArrayList
- 不传入容量默认使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA作为elementData的值,容量为0使用EMPTY_ELEMENTDATA作为elementData的值
4.方法
size 方法
public int size() {
//直接返回size,说明size是可用元素的长度
return size;
}
isEmpty 方法
public boolean isEmpty() {
//如果size等于0就表示ArrayList为空
return size == 0;
}
contains 方法
public boolean contains(Object o) {
//直接调用indexOf方法,大于等于0就表示存在
return indexOf(o) >= 0;
}
indexOf 方法
public int indexOf(Object o) {
if (o == null) {
//如果为空使用==来判断是否相等
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
//如果不为空使用equals来判断是否相等
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
- lastIndexOf方法和indexOf方法原理相同,不同在于for循环一个递增,一个递减
clone 方法
public Object clone() {
try {
//调用父类的克隆方法,此处可以看出ArrayList的克隆为浅拷贝,如果是引用类型只拷贝了引用
ArrayList<?> v = (ArrayList<?>) super.clone();
//赋值elementData的值
v.elementData = Arrays.copyOf(elementData, size);
//将修改统计数量置为0
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
toArray 方法
public Object[] toArray() {
//调用Array的copyOf方法,复制一个新的数组
return Arrays.copyOf(elementData, size);
}
//传入一个目标数组
public <T> T[] toArray(T[] a) {
if (a.length < size)
//如果目标数组的长度小于size创建一个长度为size的新数组
//再把element的内容赋值到新数组中,返回新数组
//Arrays.copyOf内部调用的也是System.arraycopy,相当于前面有一个扩容的功能
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
//如果目标数组的长度大于等于size,则直接赋值elementData的内容到目标数组中去
System.arraycopy(elementData, 0, a, 0, size);
//如果目标数组的长度大于size,把size的值置为null
if (a.length > size)
a[size] = null;
return a;
}
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];
}
set 方法
public E set(int index, E element) {
//检查数组下标是否越界
rangeCheck(index);
//获取旧值
E oldValue = elementData(index);
//设置新值
elementData[index] = element;
//返回旧值
return oldValue;
}
add 方法
public boolean add(E e) {
//检查容量,如果容量不够则需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//赋值并且将可用元素统计加1
elementData[size++] = e;
return true;
}
public void add(int index, E element) {
//检查下标的合法性
rangeCheckForAdd(index);
//检查容量,如果容量不够则需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//使用System.arraycopy进行移动,把index位置的元素向后移动一个位置,把index的位置腾出来
//性能较低
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//为index的位置赋值
elementData[index] = element;
//可用元素统计加1
size++;
}
//检查容量,如果容量不够则需要扩容
private void ensureCapacityInternal(int minCapacity) {
//如果elementData是默认初始化容量,则在默认容量和传入的容量中取最大值进行是否扩容比较
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//检查是否扩容
ensureExplicitCapacity(minCapacity);
}
//检查是否扩容
private void ensureExplicitCapacity(int minCapacity) {
//修改数量加1
modCount++;
//如果需要的容量大于elementData的长度则需要扩容
if (minCapacity - elementData.length > 0)
//扩容
grow(minCapacity);
}
//扩容函数,这是重点
//默认扩容为原容量的1.5倍
private void grow(int minCapacity) {
// 获取以前的容量
int oldCapacity = elementData.length;
//新的容量长度为旧的容量的1.5倍
//oldCapacity >> 1 等同于 oldCapacity/2
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果扩容后的容量还不够则将新容量大小替换为传入的容量大小
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新容量大于了最大可以设置的容量大小则进行最大容量检查
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 最后使用Arrays.copyOf进行扩容
elementData = Arrays.copyOf(elementData, newCapacity);
}
//最大容量检查
private static int hugeCapacity(int minCapacity) {
//如果容量超过Integer.MAX_VALUE,抛出异常
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//大于默认的最大容量返回Integer.MAX_VALUE,其他则返回最大默认容量MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
//下标合法性检查
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
remove 方法
public E remove(int index) {
//下标检查
rangeCheck(index);
//修改统计加1
modCount++;
//获取旧值
E oldValue = elementData(index);
//计算移动的个数,删除元素相当于把删除位置后面的元素向前移动一个位置,最后把末尾的值置为null
int numMoved = size - index - 1;
//如果移动数大于0,等于0表示删除最后一个元素,不存在小于0的情况
if (numMoved > 0)
//index+1位置和后面所有的元素向前移动一位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//把末尾的值置为0,并将可用元素个数减1
elementData[--size] = null; // clear to let GC do its work
//返回旧值
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 {
//元素不为空使用equals比较,遍历元素进行比较
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
//找到则移除
fastRemove(index);
return true;
}
}
//存在返回true,不存在返回false
return false;
}
private void fastRemove(int index) {
//修改统计加1
modCount++;
//计算移动的个数,删除元素相当于把删除位置后面的元素向前移动一个位置,最后把末尾的值置为null
int numMoved = size - index - 1;
//如果移动数大于0,等于0表示删除最后一个元素,不存在小于0的情况
if (numMoved > 0)
//index+1位置和后面所有的元素向前移动一位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//把末尾的值置为0,并将可用元素个数减1
elementData[--size] = null; // clear to let GC do its work
}
- 注意:remove(Object 0)方法只移除一个元素
clear 方法
public void clear() {
//修改统计加1
modCount++;
//遍历,将所有元素置为null
for (int i = 0; i < size; i++)
elementData[i] = null;
//把可用元素置为0
size = 0;
}
addAll 方法
public boolean addAll(Collection<? extends E> c) {
//将传入的Collection转换为数组
Object[] a = c.toArray();
//获取转换后的长度
int numNew = a.length;
//检查容量并扩容
ensureCapacityInternal(size + numNew); // Increments modCount
//使用System.arraycopy转换后的数组内容追加到elementData后面
System.arraycopy(a, 0, elementData, size, numNew);
//重新计算可用元素大小
size += numNew;
//如果转换后的长度不等于0返回ture反之返回false
return numNew != 0;
}
public boolean addAll(int index, Collection<? extends E> c) {
//检查下标合法性
rangeCheckForAdd(index);
//将传入的Collection转换为数组
Object[] a = c.toArray();
//获取转换后的长度
int numNew = a.length;
//检查容量并扩容
ensureCapacityInternal(size + numNew); // Increments modCount
//计算移动数量
int numMoved = size - index;
if (numMoved > 0)
//使用System.arraycopy将index位置和后面素有的元素向后移动numNew位
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
//将a的内容拷贝到elementData中去,拷贝目标位置从index处开始
System.arraycopy(a, 0, elementData, index, numNew);
//重新计算可用元素大小
size += numNew;
//如果转换后的长度不等于0返回ture反之返回false
return numNew != 0;
}
removeAll 方法
public boolean removeAll (Collection<?> c) {
//参数检查,如果参数为空,抛出异常
Objects.requireNonNull(c);
//批量移除
return batchRemove(c, false);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
//拷贝elementData
final Object[] elementData = this.elementData;
//r表示遍历的值,w表示符合条件的数量
int r = 0, w = 0;
//是否被修改
boolean modified = false;
try {
//遍历elementData
for (; r < size; r++)
//complement为false表示c中不包含该元素则把该元素加入到elementData
if (c.contains(elementData[r]) == complement)
//如果符合条件加入到elementData开始位置,并加w加1
elementData[w++] = elementData[r];
} finally {
//r不等于size表示在r的位置抛出了异常
//抛出异常后默认后面的都符合(c.contains(elementData[r]) == complement)条件
if (r != size) {
//把r后面的值拷贝到w后面去
System.arraycopy(elementData, r,
elementData, w,
size - r);
//把r到size的部分加到w上
w += size - r;
}
//如果w不等于size表示有一部分符合条件
//把w后面的部分置为null
if (w != size) {
// clear to let GC do its work
//把w后面的部分置为null
for (int i = w; i < size; i++)
elementData[i] = null;
//重新计算修改统计值
modCount += size - w;
//重新计算当前可用元素的数量
size = w;
//设置为被修改
modified = true;
}
}
return modified;
}
subList 方法
public List<E> subList(int fromIndex, int toIndex) {
//检查下标的合法性
subListRangeCheck(fromIndex, toIndex, size);
//返回一个SubList,SubList是ArrayList的一个私有的内部类
return new SubList(this, 0, fromIndex, toIndex);
}
forEach 方法
@Override
public void forEach(Consumer<? super E> action) {
//检查action是否为空,为空抛出异常
Objects.requireNonNull(action);
//拷贝一份modCount,用final修饰
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
//for循环调用action的accept
//通过modCount == expectedModCount保证for循环中ArrayList不被修改
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
//如果forEach中ArrayList被修改了,抛出异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
removeIf 方法
@Override
public boolean removeIf(Predicate<? super E> filter) {
//检查filter是否为空
Objects.requireNonNull(filter);
//初始化移除的数量为0
int removeCount = 0;
//使用BitSet来保存要移除的小标
final BitSet removeSet = new BitSet(size);
//拷贝一份modCount并用final修饰,保证ArrayList不被外部修改
final int expectedModCount = modCount;
//拷贝一份size
final int size = this.size;
//for循环遍历
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
//获取当前遍历位置的元素
final E element = (E) elementData[i];
//判断元素是否符合删除条件
if (filter.test(element)) {
//符合条件把下标记录到removeSet中
removeSet.set(i);
//删除数量加1
removeCount++;
}
}
//如果中途被修改抛出异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
//判断是否有满足删除条件的元素
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
//计算新的可用元素数量
final int newSize = size - removeCount;
//BitSet的用法还不太清楚,在这猜想是保存下标
//for循环中大概是把不删除的复制到最前面
//最后再把newSize后面的都置为null
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
//把尾部元素置为空,有效元素数量只有newSize
for (int k=newSize; k < size; k++) {
elementData[k] = null; // Let gc do its work
}
//计算新的有效元素数量
this.size = newSize;
//如果中途被修改抛出异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
return anyToRemove;
}
replaceAll 方法
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {
//检查operator是否为空,为空抛出异常
Objects.requireNonNull(operator);
//拷贝一份modCount并用final修饰,保证ArrayList不被外部修改
final int expectedModCount = modCount;
//拷贝一份size
final int size = this.size;
//for循环遍历
for (int i=0; modCount == expectedModCount && i < size; i++) {
//调用operator.apply操作每个元素
elementData[i] = operator.apply((E) elementData[i]);
}
//如果被修改则抛出异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
//修改统计加1
modCount++;
}
sort 方法
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
//拷贝一份modCount并用final修饰,保证ArrayList不被外部修改
final int expectedModCount = modCount;
//调用Arrays.sort进行排序
Arrays.sort((E[]) elementData, 0, size, c);
//如果被修改则抛出异常
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
iterator 方法
public Iterator<E> iterator() {
return new Itr();
}
- Itr是ArrayList的一个内部类
- Itr的类定义
private class Itr implements Iterator<E>
listIterator 方法
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
- ListItr是ArrayList的一个内部类
- ListItr的类定义
private class ListItr extends Itr implements ListIterator<E>