ArrayList的扩容机制详解?
请详细解释Java中ArrayList的扩容机制,包括初始容量、扩容倍数(1.5倍)、扩容的触发条件和具体实现流程(Arrays.copyOf)。说明如何指定初始容量以优化性能。
回答
古法程序员
初始容量:
- 无参构造:初始容量为0(空数组),第一次add时扩容为10
- 指定容量构造:new ArrayList(n) 使用指定初始容量
扩容倍数:
- 每次扩容为原容量的1.5倍(oldCapacity + (oldCapacity >> 1))
扩容触发条件:
- add(E e)时,size + 1 > elementData.length 触发扩容
- addAll(Collection)同理
扩容流程:
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
优化建议:
- 如果预知数据量,使用
new ArrayList<>(expectedSize)避免多次扩容 - 多次扩容涉及数组复制(O(n)),频繁扩容影响性能
Java 8的优化:无参构造使用空数组懒初始化,延迟到第一次add才创建实际数组。