ArrayList扩容代码分析

ArrayList扩容机制是在面试中频繁出现的问题,平时了解的比较含糊,特此记录!

注意:每次发生扩容,其容量扩充为原来的1.5倍 左右

add方法

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!

    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    // 是否为刚初始化后的空数组
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
    // modCount为此列表被结构修改的次数。
    // 结构修改是指改变列表的大小,或者以某种方式扰乱列表,从而导致正在进行的迭代可能产生不正确的结果。
    // 该字段由迭代器和listIterator方法返回的迭代器和列表迭代器实现使用。如果该字段的值意外更改,迭代器(或列表迭代器)将抛出ConcurrentModificationException异常,以响应next、remove、previous、set或add操作。
    // 这提供了fail-fast行为(一种错误检测机制,一旦检测到可能发生错误,就立马抛出异常,程序不继续往下执行),而不是在迭代期间面对并发修改时的非确定性行为。
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

扩容方法

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    // 这里使用的是右移计算,比整除高效(注:对于偶数是除2,对于奇数是除2向下取整,所以不完全是1.5倍)
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    // 将扩容前elementData中的数据复制出newCapacity个,没有的用null填充
    elementData = Arrays.copyOf(elementData, newCapacity);
}

主要常量及成员变量

// 默认容量
private static final int DEFAULT_CAPACITY = 10;

// 用于空实例的空数组。
private static final Object[] EMPTY_ELEMENTDATA = {};

// 默认大小的空实例。我们将它与EMPTY_ELEMENTDATA区分开来,以了解添加第一个元素时要膨胀多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

// 集合中的元素存储在其中。当ArrayList中的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,并且在其添加第一个元素时,容量将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData;

无参构造

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

Original: https://www.cnblogs.com/daydreamer-fs/p/16711980.html
Author: fogey
Title: ArrayList扩容代码分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/713411/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球