ArrayList工作原理
以数组实现,有数组容量的限制,超出限制时会增加一半的容量,用System.arraycopy()复制到新的数组。默认第一次插入元素时创建大小为10的数组。数组的元素移动使用的是System.arraycopy函数。
成员变量:存储值的数组,以及数组中的元素个数。
transient Object[] elementData;
private int size;
构造函数
- 空构造函数
public ArrayList() {
this.elementDta = DEFAULT_EMPTY_ELEMENTDATA
}
- 构造指定大小的构造函数
public ArrayList(int capacity) {
if (capacity > 0) {
this.elementData = new Object[capacity];
} else if (capacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("");
}
}
这里的EMPTY_ELEMENTDATA和DEFAULT_EMPTY_ELEMENTDATA虽然都是空数组,但是在扩容的时候,给DEFAULT_EMPTY_ELEMENTDATA添加元素时会默认扩容为10。
add函数
public boolean add(E e) {
ensureCapacityInternal(size+1);
elementData[size++] = e;
}
其中ensureCapacityInternal方法是扩容的方法。
private void ensureCapacityInternal(int minCapacity) {
// 对于空列表,默认扩容到10的容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
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);
}
// 判断最小容量是否大于最大值
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
网友评论