ArrayList简介
ArrayList 是 java 集合框架中比较常用的数据结构。继承自 AbstractList,实现了 List 接口。基于数组实现容量大小动态变化。同时还实现了 RandomAccess、Cloneable、Serializable 接口,所以ArrayList 是支持快速访问、复制、序列化的。
创建ArrayList集合时,若未指定容量,默认容量为0;
//默认创建一个空集合
transient Object[] elementData;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//ArrayList空参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
当集合对象调用add方法存储数据时,进行容量初始化。底层实现如下:
//ArrayList集合对象添加元素方法
public boolean add(E e) {
modCount++;
//add中有容量初始化方法grow()
add(e, elementData, size);
return true;
}
//grow()方法进行容量初始化,执行else{}
private static final int DEFAULT_CAPACITY = 10;
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
//初始化为容量为DEFAULT_CAPACITY的值
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
结论1:
当集合对象第一次添加元素的时候,集合大小扩容为10(若使用addAll方法添加元素,则初始化大小为10和添加集合长度的较大值)
初始化完成后,再添加元素,重复上面的步骤,不同的是grow()方法执行的是if()的内容,开始扩容
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
结论2:
当再次调用add方法时,先将集合扩大原来的1.5倍,如果仍然不够,通过Arrasys.copyof()将长度传入新集合中,再次进行扩容
总结
1.ArrayList创建对象时,若未指定集合大小初始化大小为0;若已指定大小,集合大小为指定的大小;
2.当第一次调用add方法时,集合长度变为10和原指定集合大小之间的较大值;
3.之后再调用add方法,先将集合扩大1.5倍,如果仍然不够,通过Arrasys.copyof()将长度传入新集合中,再次进行扩容;