ArrayList源码(构造器和扩容机制)

ArrayList源码

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

成员变量

private static final int DEFAULT_CAPACITY = 10;
​
​
    private static final Object[] EMPTY_ELEMENTDATA = {};
​
​
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
​
​
    transient Object[] elementData; // non-private to simplify nested class access
​
​
    private int size;

首先是用 DEFAULT_CAPACITY 定义了一个默认常量

然后定义了两个空数组 EMPTY_ELEMENTDATA 和 DEFAULTCAPACITY_EMPTY_ELEMENTDATA

在使用的过程中,会有很多的地方都会用到空数组,所以定义为静态常量可以减少内存的开销

这两个数组主要的区别为: EMPTY_ELEMENTDATA 是为了避免产生不必要的空数组,让所有的空数组都指向同一个位置

DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是为了确保在调用互参构造器的条件下添加第一个元素时,

默认的初始容量为DEFAULT_CAPACITY 也就是10

构造器

// 传入一个初始化容量,如果传入的数字大于零,则创建一个容量为 initialCapacity 的Object类型的数组
// 如果等于零,则引用一个空数组
// 因为容量不能小于零,所以当传入的数字小于零时,抛出一个异常
public ArrayList(int initialCapacity) {  
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}
​
// 空参构造器,直接用DEFAULTCAPACITY_EMPTY_ELEMENTDATA
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
​
// 传入了一个集合,如果这个集合的为空,直接传一个空数组,
// 不为空,就判断是不是一个数组,是的话直接拷贝到elementData
public ArrayList(Collection c) {
    Object[] a = c.toArray();
    if ((size = a.length) != 0) {
        if (c.getClass() == ArrayList.class) { // 判断是不是一个数组
            elementData = a;
        } else {
            elementData = Arrays.copyOf(a, size, Object[].class);
        }
    } else {
        // replace with empty array.
        elementData = EMPTY_ELEMENTDATA;
    }
}
 
  

扩容机制

// 传入一个最小容量,如果最小容量大于数组的长度 并且 这个数组不是DEFAULTCAPACITY_EMPTY_ELEMENTDATA且小于DEFAULT_CAPACITY
// 就需要调用grow方法进行扩容
 public void ensureCapacity(int minCapacity) {
        if (minCapacity > elementData.length
            && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
                 && minCapacity <= DEFAULT_CAPACITY)) {
            modCount++;
            grow(minCapacity);
        }
    }
​
// 传入所需的最小容量,
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); // 将扩充完的数组拷贝下来
}

你可能感兴趣的:(java,开发语言)