我们都知道jdk1.6的时候,ArrayList默认长度为10
但是jdk1.8之后,发生了变化
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
我们看到默认数组直接赋值为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
显然如果在初始化集合时不初始化数组容量(或者说长度),该数组的默认长度为0;
初始化长度为0的数组,怎么添加数据?下面我们讨论添加第一个元素的过程
我们看集合的add方法
在添加元素时;会先去判断集合是否需要扩容;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
elementData是存放元素的数组;
minCapacity=size + 1(size:当前元素个数)
我们先看calculateCapacity(elementData, minCapacity)的返回值
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
添加第一个元素时:
elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA;(进入if条件分支)
minCapacity=0+1=1;
显然返回值为:DEFAULT_CAPACITY(10)
下面接着看ensureExplicitCapacity()方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
上一步的返回值minCapacity=10;
数组长度:elementData.length=0;
进入grow方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
我们来看变量的值:
minCapacity=10;
oldCapacity = elementData.length=0;
newCapacity = oldCapacity + (oldCapacity >> 1)=0;
if (newCapacity - minCapacity < 0) //0-10<0;
newCapacity = minCapacity=10;
elementData = Arrays.copyOf(elementData, newCapacity);//将原数组的值复制到新数组,并且将数组的长度扩大到newCapacity(10);
因此我们可以看到,在添加第一个元素的时候,集合的长度改变为10;
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
在0
jdk1.8之后:
1.ArrayList初始集合不初始化数组容量的时候,默认值为0
2.添加元素后,扩容为10,之后每次扩容为原来的0.5倍