private transient Object[] elementData;
private int size;
protected transient int modCount = 0;//AbstractList类中
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
this(10);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//old=10
int newCapacity = oldCapacity + (oldCapacity >> 1);//newCapacity=10+10/2=15
if (newCapacity - minCapacity < 0)//15-11>0->不执行
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//15-Integer.MAX_VALUE - 8<0 不执行
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//Arrays类中的方法
} //public static <T> T[] copyOf(T[] original,int newLength)
//将产生一个新的数组:元素是elementData中的元素,长度是newCapacity
//发现它又重新赋值给了elementData->即elementData指向新数组
private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)//句话当11-10>0时
grow(minCapacity);//grow(11)->扩充
}
默认ArrayList 不带参数,初始化数组时比如以下代码:
private transient Object[] elementData;
this.elementData = new Object[10];
大家看一下transient ,这是设计者不让集合序列化的时候还保持原有数据;
当每次在添加add集合的时候,会判断elementData 的长度是不是超过了当前总长度的一半,现在示例是10,那么就是5;
如果当集合长度超过5,则开辟一个新的扩容数组;
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);(注意右移一位除以2,即加一般容量)
this.elementData = new Object[newCapacity ];
等于说现在巅峰内存是 10(驻留在内存中的数据),和现在开辟的15数据,一共是25;
然后把以前的值Arrays.copyOf(elementData, newCapacity) 复制进新数组,为什么使用Arrays.copyOf,因为其内部实现是 public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);