JDK6: 默认初始化的时候 ArrayList容量就是10
JDK7+ : 默认的容量表面上是0,其实还是10 ,只是使用懒加载,当使用add方法添加一个元素时,容量会被扩成10 ,
这算是一个优化,如果实例化后没有添加元素,容量是0,节约空间,否则为10
实现扩容:
jdk7中采用
>>位运算,右移动一位。 容量相当于扩大了1.5倍;
举例说明:添加20个元素到ArrayList中
当第一次插入元素时才分配10(默认)个对象空间。之后扩容会按照1.5倍增长。
也就是当添加第11个数据的时候,Arraylist继续扩容变为10*1.5=15;
当添加第16个数据时,继续扩容变为15 * 1.5 =22个;
总结:
在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。
在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为
原来的1.5倍加1
.以上就是动态扩容的原理。
在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。
在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为
1:JDK6
// JDK6的扩容机制
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);
}
}
// 默认容量大小是10
public ArrayList() {
this(10);
}
2:JDK7
<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 用位运算,相当于扩容1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
/** JDK7+ 默认的容量表面上是0,其实还是10
*,只是使用懒加载,当使用add方法添加一个元素时,容量会被扩成10 ,
*这算是一个优化,如果实例化后没有添加元素,容量是0,节约空间,否则为10
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
// 当添加元素时,这里有懒加载设置容量 ,
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}