首先看类定义:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
private transient Object[] elementData;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}
使用无参的构造方法时,ArrayList将我们初始一个长度为10的Object[]数组
下面再看看 add函数
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
调用add函数时会将当前数组的长度+1后,通过ensureCapacity 函数进行判断数组大小是否可用,如果超过可用大小,那么ArrayList底层会生成一个新的数组,长度为原数组的1.5倍+1,值得关注的是Arrays.copyOf(elementData, newCapacity);
我们再看下移除函数
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
删除数组元素的时候,也会进行System.arraycopy..要将被删除元素的后续元素向前移动
总结:
ArrayList:
1) ArrayList底层使用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组
2) 如果生成的数组超过10个,那么ArrayList底层会生成一个新的数组,长度为原数组的1.5倍+1,然后将原数组的元素复制到新数组之中,并且后续增加的内容都会放到新数组之中,当新数组无法容纳增加的元素时,重复该过程
3) 对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高