写博客只是作为学习笔记!
简单的理解ArrayList的扩容机制
先看看部分源码:
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//注意这里是EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//DEFAULTCAPACITY_EMPTY_ELEMENTDATA
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
扩容:
private void ensureCapacityInternal(int minCapacity) {
//判断是否为空数组
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //如果为空数组,则默认容量为10,对比默认容量大于传进来的大小,取最大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果传入的容量大小大于数组大小,则才需要扩容
if (minCapacity - elementData.length > 0)
//主要是grow方法进行扩容
grow(minCapacity);
}
private void grow(int minCapacity) {
// 获取数组原本的大小
int oldCapacity = elementData.length;
//扩容,右位移一位,1+0.5 扩容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);
}
接下来自己写代码debug走一次看看:
打断点的几个方法:
debug开始:
对比一下ensureCapacity方法和ensureCapacityInternal方法的区别
先看源码:
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
代码验证一下:
public static void main(String[] args) {
List list = new ArrayList();
long start = System.currentTimeMillis();
for (int i =0;i<10000000;i++){
list.add(i);
}
long end = System.currentTimeMillis();
System.out.println("普通方法所需要的时间:" + (end - start) + "ms");
//=================================================
long start1 = System.currentTimeMillis();
List list1 = new ArrayList();
((ArrayList) list1).ensureCapacity(10000000);
for (int i =0;i<10000000;i++){
list1.add(i);
}
long end1 = System.currentTimeMillis();
System.out.println("ensureCapacity()需要的时间:" + (end1 - start1) + "ms");
}
you complete me ——胡小宝