经常用到ArrayList,知道和LinkedList的对比优缺点,但是没那么读过源码。
首先它继承了AbstractList,实现了List接口,RandomAccess接口(支持快速随机访问,查询快的标记接口),Cloneable接口,序列化接口。
初始化参数:
// 初始容量为10
private static final int DEFAULT_CAPACITY = 10;
// 空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认空数组实例,区别于上面的就是第一个元素添加时候增长多少
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 存储数组缓冲区,ArrayList的容量就是此数组的长度,第一个元素添加的时候,数组容量从0变10
transient Object[] elementData;
// 大小
private int size;
// ArrayList被修改的次数,初始值为0,来自父类
protected transient int modCount = 0;
// 最大容量,为2的31次方-1 ,再减8,除非有必要再使用,否则可能有些jvm会OutOfMemoryError报错
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
三个构造函数,不带参数,带容量大小参数,带集合参数:
// 创建指定容量的ArrayList
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
// 指定容量大于0,那么创建一个Object[initialCapacity]的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
// 指定容量小于0,那么等于空数组实例
this.elementData = EMPTY_ELEMENTDATA;
} else {
// 指定容量小于0,抛出异常 : IllegalArgumentException
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
// 不带参数的构造函数,创建一个容量为10的ArrayList
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 参数为集合的构造函数,顺序为集合迭代器返回顺序
public ArrayList(Collection<? extends E> c) {
// 集合转换为数组
elementData = c.toArray();
// 如果数组大小不为0
if ((size = elementData.length) != 0) {
// 防止没有返回对象数组的错误
if (elementData.getClass() != Object[].class)
// 元素拷贝创建ArrayList
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// 否则创建一个空ArrayList
this.elementData = EMPTY_ELEMENTDATA;
}
}
trimToSize()方法:压缩容量到实际大小
public void trimToSize() {
// 修改次数+1
modCount++;
// 如果真实大小小于容量
if (size < elementData.length) {
// 当大小等于0时候为空数组
elementData = (size == 0)
? EMPTY_ELEMENTDATA
// 当大小不等于0的时候复制真实数组
: Arrays.copyOf(elementData, size);
}
}
确保容量方法ensureCapacity(int minCapacity)
public void ensureCapacity(int minCapacity) {
// 如果参数minCapacity大于真实长度
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) {
// 增加修改次数
modCount++;
// 扩容
grow(minCapacity);
}
}
// 扩容成新的大小数组
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
// 计算新容量方法
private int newCapacity(int minCapacity) {
// 老容量为真实长度
int oldCapacity = elementData.length;
// 新容量为老容量*1.5
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果新容量小于minCapacity,则返回minCapacity
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
// 无参增长新容量
private Object[] grow() {
return grow(size + 1);
}
// 判断是否大于最大容量,小于的话返回新容量,大于的话直接返回最大容量
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
// 创建最大容量的静态方法
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)
? Integer.MAX_VALUE
: MAX_ARRAY_SIZE;
}
size() 方法返回size
public int size() {
return size;
}
isEmpty() 方法返回是否为空
public boolean isEmpty() {
return size == 0;
}
contains(Object o) 方法返回是否包含某个对象
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
indexOf(Object o) 方法返回第一个找到该对象的index,如果找不到 返回-1
public int indexOf(Object o) {
// 从0位找到最后位
return indexOfRange(o, 0, size);
}
// 找到对象从start到end之间的index,遍历数组
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
// 判断两个值是否相等,相等返回
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
lastIndexOf(Object o) 方法,找到最后一个该对象的index,没有则-1
// 同上,从尾部开始遍历,返回
public int lastIndexOf(Object o) {
return lastIndexOfRange(o, 0, size);
}
int lastIndexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = end - 1; i >= start; i--) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = end - 1; i >= start; i--) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
clone() 方法,返回一个浅拷贝,元素本身不会被复制
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
// 调用Arrays中的copyOf方法
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
// 以下为Arrays中的方法
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
//以下为System中的arraycopy方法
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
toArray()方法,返回一个包含所有元素的数组
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
get(int index)方法,返回index元素
public E get(int index) {
Objects.checkIndex(index, size);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
// 以下为Objects的方法,检查index是否在范围内
public static int checkIndex(int index, int length) {
return Preconditions.checkIndex(index, length, null);
}
//以下为Preconditions的方法,如果index在范围外则抛出outOfBoundsCheckIndex异常
public static <X extends RuntimeException>
int checkIndex(int index, int length,
BiFunction<String, List<Integer>, X> oobef) {
if (index < 0 || index >= length)
throw outOfBoundsCheckIndex(oobef, index, length);
return index;
}
set(int index, E element)方法,修改指定index处的值,并返回旧值
public E set(int index, E element) {
// 检查index范围
Objects.checkIndex(index, size);
// 得到旧值
E oldValue = elementData(index);
// 更换新值
elementData[index] = element;
// 返回旧值
return oldValue;
}
add(E e) 方法,在list末尾加上e,返回boolean
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
// 扩容
elementData = grow();
elementData[s] = e;
size = s + 1;
}
add(int index, E element)方法,指定index位置插入值,并且当前和之后受影响元素后移,无返回值
public void add(int index, E element) {
// 检查index是否在范围内,不在的话抛出IndexOutOfBoundsException异常
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
remove(int index)方法,返回被移除对象
public E remove(int index) {
Objects.checkIndex(index, size);
final Object[] es = elementData;
E oldValue = (E) es[index];
fastRemove(es, index);
return oldValue;
}
private void fastRemove(Object[] es, int i) {
modCount++;
final int newSize;
if ((newSize = size - 1) > i)
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
很多操作中都会出现的System.arraycopy数组复制方法,是一种native的方法
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
参数
src: 原始数组
srcPos:原始数组的起始位置
dest: 目标数组
destPos: 目标数组的起始位置
length: 复制元素的数量
clear()方法,清空,无返回值,循环设置null,size设为0
public void clear() {
modCount++;
final Object[] es = elementData;
for (int to = size, i = size = 0; i < to; i++)
es[i] = null;
}
addAll(Collection<? extends E> c) 方法,添加集合,返回boolean
public boolean addAll(Collection<? extends E> c) {
// 首先集合转对数组
Object[] a = c.toArray();
// 增加修改次数
modCount++;
// 获得对象数组长度
int numNew = a.length;
// 长度为0返回false
if (numNew == 0)
return false;
Object[] elementData;
final int s;
// 如果新增容量大于ArrayList的剩余容量则进行扩容
if (numNew > (elementData = this.elementData).length - (s = size))
elementData = grow(s + numNew);
// 复制对象数组到ArrayList中
System.arraycopy(a, 0, elementData, s, numNew);
size = s + numNew;
return true;
}
addAll(int index, Collection<? extends E> c) 增加集合到数组中,从index开始,返回值为boolean,具体操作和上面差不多,只是起始位置,复制个数修改一下
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
modCount++;
int numNew = a.length;
if (numNew == 0)
return false;
Object[] elementData;
final int s;
if (numNew > (elementData = this.elementData).length - (s = size))
elementData = grow(s + numNew);
int numMoved = s - index;
if (numMoved > 0)
System.arraycopy(elementData, index,
elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size = s + numNew;
return true;
}
void removeRange(int fromIndex, int toIndex)方法,移除fromIndex和toIndex之间的元素,包括fromIndex但是不包括toIndex
protected void removeRange(int fromIndex, int toIndex) {
// 判断参数是否正确
if (fromIndex > toIndex) {
throw new IndexOutOfBoundsException(
outOfBoundsMsg(fromIndex, toIndex));
}
// 增加修改次数
modCount++;
// 内部方法移除
shiftTailOverGap(elementData, fromIndex, toIndex);
}
private void shiftTailOverGap(Object[] es, int lo, int hi) {
// 从toIndex开始之后的数组,移动到fromIndex位置开始
System.arraycopy(es, hi, es, lo, size - hi);
// 把容量之外的元素变成null
for (int to = size, i = (size -= hi - lo); i < to; i++)
es[i] = null;
}
boolean removeAll(Collection<?> c) 方法,移除ArrayList中所有c中的元素
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false, 0, size);
}
boolean batchRemove(Collection<?> c, boolean complement,
final int from, final int end) {
// 检查不为null
Objects.requireNonNull(c);
final Object[] es = elementData;
int r;
// 如果c中不包含ArrayList中的元素,那么直接返回false,否则向下执行, 同时r定位到第一个包含的位置
for (r = from;; r++) {
if (r == end)
return false;
if (c.contains(es[r]) != complement)
break;
}
// w定位到r下一个位置
int w = r++;
try {
for (Object e; r < end; r++)
if (c.contains(e = es[r]) == complement)
// 利用w指针记录如果c中包含的元素,那么就删除
es[w++] = e;
} catch (Throwable ex) {
System.arraycopy(es, r, es, w, end - r);
w += end - r;
throw ex;
} finally {
modCount += end - w;
// 移除w和end之间的元素
shiftTailOverGap(es, w, end);
}
return true;
}
// Objects中如果对象参数为null则抛出异常的方法
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
ListIterator listIterator(int index)方法,返回一个list iterator, 从index处开始。
public ListIterator<E> listIterator(int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
List subList(int fromIndex, int toIndex) 方法返回一个范围内的子类
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList<>(this, fromIndex, toIndex);
}
void writeObject(java.io.ObjectOutputStream s) 方法,序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioral compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
void readObject(java.io.ObjectInputStream s)方法,反序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// like clone(), allocate array based upon size not capacity
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
Object[] elements = new Object[size];
// Read in all elements in the proper order.
for (int i = 0; i < size; i++) {
elements[i] = s.readObject();
}
elementData = elements;
} else if (size == 0) {
elementData = EMPTY_ELEMENTDATA;
} else {
throw new java.io.InvalidObjectException("Invalid size: " + size);
}
}
ArrayList中包含了四个内部类
private class Itr implements Iterator<E>
private class ListItr extends Itr implements ListIterator<E>
private static class SubList<E> extends AbstractList<E> implements RandomAccess
final class ArrayListSpliterator implements Spliterator<E>
更详细内容可以参考:link