//ArrayList容器为数组
transient Object[] elementData;
//数组实际存储的元素数量
private int size;
//构造函数
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//添加一个元素
public boolean add(E e) {
//确保内部容量
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//minCapacity为当前存储元素数量+1
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//如果当前数组的容量为初始容量(10)
//则将比较当前实际容量+1与初始容量做比较,返回较大的数值
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
//若当前数组的容量已经不再是初始容量(0),直接返回 Size+1
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
//检测到并发性的标识
modCount++;
//需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//扩容方式
private void grow(int minCapacity) {
// 当前数组中实际元素的个数
int oldCapacity = elementData.length;
// 容量括增50%
int newCapacity = oldCapacity + (oldCapacity >> 1);
//增加50%后的容量小于实际需要的容量
if (newCapacity - minCapacity < 0)
//将容量增至实际需要的容量
newCapacity = minCapacity;
//是否超出要分配的最大数组大小
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//真正扩容的实现
elementData = Arrays.copyOf(elementData, newCapacity);
}
//常量MAX_ARRAY_SIZE
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//高容量扩充
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//需要的容量如果大于MAX_ARRAY_SIZE,则将Integer.MAX_VALUE返回
//若小于等于MAX_ARRAY_SIZE,则返回MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
// 位置访问操作
E elementData(int index) {
return (E) elementData[index];
}
//移除指定位置上的元素
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);
//最后一个元素还在没变,将其复制为null,GC垃圾回收。
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
//从指定的源数组复制数组,从指定位置,到目标数组的指定位置。
//src 源数组
// srcPos 在源数组中的起始位置
// dest 目标数组
// destPos 在目标数据中的起始位置
// 要复制的数组元素的数量
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
//在数组访问之前使用,检查索引是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//判断ArrayList是否为空
public boolean isEmpty() {
return size == 0;
}
ArrayList源码分析
最新推荐文章于 2024-08-22 16:13:15 发布