1.属性变量
private static final int DEFAULT_CAPACITY = 10; //默认数组容量
private static final Object[] EMPTY_ELEMENTDATA = {} //用于将elementData赋值为空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}//主要参与决定扩容时扩容量的大小。
transient Object[] elementData;//数组缓冲区,数组列表的元素存储在其中。ArrayList 的容量是此数组缓冲区的长度。添加第一个元素时,任何带有 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空 ArrayList 都将展开为DEFAULT_CAPACITY。
private int size;//list中的元素个数
2.构造方法
//指定初始容量的构造方法
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];//容量参数大于0时实例化对应长度的数组赋值给元素数组
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;//容量参数等于0时将EMPTY_ELEMENTDATA这个空数组赋值给元素数组
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//无参构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//将元素数组赋值为空数组
}
public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
3.常用方法
//根据索引获取元素
public E get(int index) {
rangeCheck(index);//判断索引是否大于等于size即元素个数
return elementData(index);
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(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); // 当前元素个数加一并开始进行扩容逻辑
elementData[size++] = e;
return true;
}
//扩容流程:确定长度 -> 长度大于当前元素数组长度 -> 进行扩容
//minCapacity代表是扩容后的元素数组长度
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//确定扩容以后的元素数组长度
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//判断扩容时集合是否为空集合
//选取10与minCapacity之间的最大值返回
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
//比较长度是否进行扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 扩容的触发条件当minCapacity大于elementData长度时才开始真正的扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//扩容逻辑代码
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//每次扩容默认增加原长度的一半
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//当新长度大于Integer.MAX_VALUE - 8时进行扩容长度的处理(注:Integer.MAX_VALUE 为2的31次方减一)
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 void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // 扩容逻辑
System.arraycopy(elementData, index, elementData, index + 1,
size - index);//将元素向后平移
elementData[index] = element;
size++;
}
//根据索引删除元素
public E remove(int index) {
rangeCheck(index);//判断索引是否合法
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;//计算删除元素后需要向前平移的元素个数
if (numMoved > 0)
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++;
int numMoved = size - index - 1;//计算平移的元素个数
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 将元素置为空方便GC回收
}
//清空方法
public void clear() {
modCount++;
// 元素置为空GC回收
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); //扩容逻辑
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); // 扩容
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;
}
//删除指定集合元素
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
//取交集
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(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];
} finally {
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// 将不符合条件的元素置为空方便GC回收
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}