ArrayList是一个动态数组容器,实现了List接口的所有方法,并且可以容纳null,和C++中的vector一样。底层用一个数组来组织数据,所有的方法都是围绕着这个数组进行的。除此之外,ArrayList还提供了两个公有API来对数组大小的操作,分别是trimToSize与ensureCapacity。ArrayList是我们平常使用比较多的一个集合类,掌握它的源码有助于我们更好的使用它。
ArrayList源码如下:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//AbstractList 与 List 的源码与关系在之前的文章中已经分析过了。
//RandomAccess是随机访问接口,可以在O(1)时间内根据所以返回元素。
//Cloneable表示可以被克隆(这个拷贝是浅拷贝)。序列化接口Serializable。
private static final long serialVersionUID = 8683452581122892189L;
//默认数组的容量大小
private static final int DEFAULT_CAPACITY = 10;
//空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//通过无参构造器,也即 new ArrayList<>(),生成对象时的默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 以下两个成员变量 elementData与size是ArrayList最主要的两个变量,所有的方法都是围绕着它们两
//储存元素的数组
transient Object[] elementData;
//集合元素的大小
private int size;
//构造函数
//给elementData数组一个初始大小
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);
}
}
//无参构造函数
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//通过其它集合来初始化elementData
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray(); // toArray 集合与数组之间的转化桥梁
if ((size = elementData.length) != 0) {
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class) // 意思是如果 toArray 返回类型不是 Object[] ,那么在重新复制一份
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
}
分析完构造函数之后,下面分析两个对数组elementData大小直接操作的两个函数
//缩减elementData数组的大小,使其刚好等于集合大小
public void trimToSize() {
modCount++; // modCount 继承自AbstractList
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
//确保elementData的大小至少为minCapacity.这个函数是给外界调用的,在ArrayList里面并没有使用到这个函数
public void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length
&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
&& minCapacity <= DEFAULT_CAPACITY)) { // 当ArrayList对象是通过无参构造函数创建且minCapacity小于等于DEFAULT_CAPACITY(10)时,什么也不做。
modCount++;
grow(minCapacity);
}
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}
private Object[] grow() {
return grow(size + 1);
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //每次扩容1.5倍
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
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;
}
查询操作源码:
// 返回长度
public int size() {
return size;
}
//判断是否为空
public boolean isEmpty() {
return size == 0;
}
//判断是否包含对象o
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//返回对象o的索引,不存在就返回-1
public int indexOf(Object o) {
return indexOfRange(o, 0, size);
}
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;
}
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;
}
E elementData(int index) {
return (E) elementData[index];
}
public E get(int index) {
Objects.checkIndex(index, size); //检测输入是否合法
return elementData(index);
}
修改操作:
//更改指定索引处的元素
public E set(int index, E element) {
Objects.checkIndex(index, size);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow(); // 如果索引s等于elementData数组的容量,扩容
elementData[s] = e; // 插入
size = s + 1; // 更新size
}
// 添加元素到末尾
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
// 在指定索引处插入元素
public void add(int index, E element) {
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); // index处之后的元素向后移一位,为新插入的元素腾空间
elementData[index] = element;
size = s + 1;
}
//根据索引删除元素,返回删除的元素
public E remove(int index) {
Objects.checkIndex(index, size);
final Object[] es = elementData;
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
fastRemove(es, index);
return oldValue;
}
//根据对象删除元素
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found; // 带标签的break语法
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
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;
}
public void clear() {
modCount++;
final Object[] es = elementData;
for (int to = size, i = size = 0; i < to; i++)
es[i] = null;
}
批量修改操作源码:
// 添加集合c中的所有元素到末尾
public boolean addAll(Collection<? extends E> c) {
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能否容纳集合c中的所有元素,不能就扩容
elementData = grow(s + numNew);
System.arraycopy(a, 0, elementData, s, numNew);
size = s + numNew;
return true;
}
//在指定位置添加集合c中的所有元素
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index); // 检测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); //将index之后的元素向后移
System.arraycopy(a, 0, elementData, index, numNew);
size = s + numNew;
return true;
}
// 删除集合c中的所有元素
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false, 0, size);
}
// 保留那些集合c与elementData都有的元素
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true, 0, size);
}
boolean batchRemove(Collection<?> c, boolean complement,
final int from, final int end) {
Objects.requireNonNull(c); // 确保集合c不为null
final Object[] es = elementData;
int r;
// Optimize for initial run of survivors
// 优化初始位置
for (r = from;; r++) {
if (r == end)
return false;
if (c.contains(es[r]) != complement)
break;
}
// 其实就是两层for循环,时间复杂度为O(n^2)。contains是线性搜索,时间复杂度为O(n)
int w = r++;
try {
for (Object e; r < end; r++)
if (c.contains(e = es[r]) == complement)
es[w++] = e;
} catch (Throwable ex) {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
System.arraycopy(es, r, es, w, end - r);
w += end - r;
throw ex;
} finally {
modCount += end - w;
shiftTailOverGap(es, w, end);
}
return true;
}
// 将从索引hi开始的元素移到从lo开始,也就是抹掉lo---hi 之间的元素 (左闭右开)
private void shiftTailOverGap(Object[] es, int lo, int hi) {
System.arraycopy(es, hi, es, lo, size - hi);
for (int to = size, i = (size -= hi - lo); i < to; i++)
es[i] = null;
}
重写Object类的源码:(比较简单,直接看就明白了)
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof List)) {
return false;
}
final int expectedModCount = modCount;
// ArrayList can be subclassed and given arbitrary behavior, but we can
// still deal with the common case where o is ArrayList precisely
boolean equal = (o.getClass() == ArrayList.class)
? equalsArrayList((ArrayList<?>) o)
: equalsRange((List<?>) o, 0, size);
checkForComodification(expectedModCount);
return equal;
}
boolean equalsRange(List<?> other, int from, int to) {
final Object[] es = elementData;
if (to > es.length) {
throw new ConcurrentModificationException();
}
var oit = other.iterator();
for (; from < to; from++) {
if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) {
return false;
}
}
return !oit.hasNext();
}
private boolean equalsArrayList(ArrayList<?> other) {
final int otherModCount = other.modCount;
final int s = size;
boolean equal;
if (equal = (s == other.size)) {
final Object[] otherEs = other.elementData;
final Object[] es = elementData;
if (s > es.length || s > otherEs.length) {
throw new ConcurrentModificationException();
}
for (int i = 0; i < s; i++) {
if (!Objects.equals(es[i], otherEs[i])) {
equal = false;
break;
}
}
}
other.checkForComodification(otherModCount);
return equal;
}
private void checkForComodification(final int expectedModCount) {
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
public int hashCode() {
int expectedModCount = modCount;
int hash = hashCodeRange(0, size);
checkForComodification(expectedModCount);
return hash;
}
int hashCodeRange(int from, int to) {
final Object[] es = elementData;
if (to > es.length) {
throw new ConcurrentModificationException();
}
int hashCode = 1;
for (int i = from; i < to; i++) {
Object e = es[i];
hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
}
return hashCode;
}
迭代器Iterator与listIterator的实现类与上一篇的实现几乎是一样的。