以下是ArrayList的add()方法的源码
import java.util.Arrays;
public class NewArraylist<E> {
transient Object[] elementdata;
private static final Object[] Dafaultapacity_empty_elemendate = {};
private static final int DEFAULT_CAPACITY = 10;
private int size = 0;
public NewArraylist(){
this.elementdata = Dafaultapacity_empty_elemendate;
}
public boolean add(E e){
ensureCapacityInternal(size + 1);
elementdata[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity){
ensureExplicitCapacity(calculateCapacity(elementdata, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {//让初始动态数组为空时,计算需要的容量是10还高于10
if(elementData == Dafaultapacity_empty_elemendate) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
// modCount++;
// overflow-conscious code
if (minCapacity - elementdata.length > 0)
grow(minCapacity);//需要的容量大于目前的容量,执行扩容
}
private void grow(int minCapacity){
int oldCapacity = elementdata.length;
int newCapacity = oldCapacity + (oldCapacity>>1);
if(newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementdata = Arrays.copyOf(elementdata, newCapacity);
}
}
我们自己写的一般是创建一个比原来数组大一位的数组,然后把原来数组的元素全部复制到新数组。但是通过添加十万个数据的运行速度比较来看,源码的运行所需要的时间明显比我们自己的血代码花费的少。
原因是在于,它避免了不必要的数组复制。在一般的代码中,每次扩展数组时,都会调用System.arraycopy,这会创建一个新数组,并从旧数组中复制所有元素。如果数组很大,或者如果添加了许多元素,会导致花费的资源更多。而源码就会对需要的最小容量和原数组的自身容量进行对比才会触发扩容操作。