在进行源码分析时,我们需要知道ArrayList底层是什么
ArrayList底层是可扩容的动态数组
private static final int DEFAULT_CAPACITY = 10; //默认容量10
private static final Object[] EMPTY_ELEMENTDATA = {}; //空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认容量空数组
transient Object[] elementData; //动态数组
private int size; //元素个数
1、ArrayList构造器
//无参
public ArrayList() {
//构造一个空数组
this.elementData = DEFAULTCAPACITY_EMPTY_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);
}
}
2、add(E):向后添加
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 确保容量足够
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //第一次无参构造时,让下面的grow的参数为DEFAULT_CAPACITY,也就是10
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //先不用管,我也不知道
if (minCapacity - elementData.length > 0)
grow(minCapacity); //动态扩容
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //旧容量为0
int newCapacity = oldCapacity + (oldCapacity >> 1); //新容量为旧容量的1.5倍,还是0
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; //等于10就完事了
if (newCapacity - MAX_ARRAY_SIZE > 0) //这个条件是防止数组的容量超过int类型最大值
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity); //工具类方法,短数组变长数组,原数据不变
}
3、remove(int):删除索引
public E remove(int index) {
rangeCheck(index); //检查索引是否越界
modCount++; //不用管,但如果你会的话请告诉我
E oldValue = elementData(index); //取出待删除元素的值
int numMoved = size - index - 1; //记录一下待删除元素之后的元素个数,作为System.arraycopy的参数使用
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved); //工具类方法,数组移动
elementData[--size] = null; //数组移动的时候,原来的最后一个元素仅仅是向前赋值,最后一个位置还有值,所以置null值
return oldValue; //返回待删除元素
}