初始化arraylist请童鞋们自己去百度,我们从添加开始看
点开arraylist的源码,查看add方法,初始化的size进行+1作参
看见没,数组的第++个元素等于参数,懂吧
private int size;
transient Object[] elementData;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
点开ensureCapacityInternal方法
transient Object[] elementData;
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
首先调用了calculateCapacity方法,参数elementData以及我们传递的size+1;
再进入calculateCapacity方法
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private static final int DEFAULT_CAPACITY = 10;
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
第一次添加,两个初始化的数组必然相等,那么根据max方法的比较,返回的是DEFAULT_CAPACITY也就是10,因为我minCapacity才第一次,就是个1,下次再来就不相等了
再进入ensureExplicitCapacity方法
protected transient int modCount = 0;
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
第一次比较,肯定不会是大于0的,所以要看的就是当我在calculateCapacity方法中已经大于10的情况下,才会执行grow方法,也就是扩容
private void grow(int minCapacity) {
// overflow-conscious code
//拿来老长度
int oldCapacity = elementData.length;
//这是新长度,老长度右移一位,代表除以2,newCapacity等于1.5oldCapacity
int newCapacity = oldCapacity + (oldCapacity >> 1);
//新长度是否满足要求
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新长度还不能满足,那么就进入hugeCapacity方法
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// arrays的方法,原本的数组(elementData),新长度(newCapacity),新的数组产生,包含原数组中的元素
elementData = Arrays.copyOf(elementData, newCapacity);
}
hugeCapacity方法
private static int hugeCapacity(int minCapacity) {
//小于0这是出问题了,抛异常
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//判断,小于最大的长度,那么就返回integet类型的最大长度,大于就是array的最大长度
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
这样新数组就elementData 就产生了
其实也不是只有Arrays.copyOf这一种,面试被问到了特意查的,面试结果是失败了,没办法,自己菜,没鼓捣过。
System.arraycopy也能行
src:原数组
srcPos:原数组起始位置
dest:目标数组
destPos:目标数组开始位置
length:要复制的元素长度
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
这就是建一个新数组,然后吧原来数组的元素通过索引位置以及要复制的长度,给到新索引的开始位置而已。
告辞!