ArrayList源码分析

部分成员变量

  • private static final int DEFAULT_CAPACITY = 10;
    默认数组大小

  • private static final Object[] EMPTY_ELEMENTDATA = {};
    一个空的数组

  • private transient Object[] elementData;
    ArrayList实际上存储元素的数组

  • private int size;
    ArrayList实际包含的元素


构造函数

默认构造方法,指向一个空的数组

public ArrayList() {
    super();
    //初始化数组,指向空数组
    this.elementData = EMPTY_ELEMENTDATA;
}

用一个Collection对象来实例化ArrayList

public ArrayList(Collection c) {
    elementData = c.toArray();
    size = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, size, Object[].class);
}

指定初始容量初始化ArrayList

public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }

主要方法实现

add(E):boolean

public boolean add(E e) {
    //判断是否需要扩容
   ensureCapacityInternal(size + 1);  // Increments modCount!!
   elementData[size++] = e;
   return true;
}

private void ensureCapacityInternal(int minCapacity) {
    //如果数组为空,取(默认数组大小,当前数组包含元素数量+1)的最大值
    if (elementData == 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) {
   // overflow-conscious code
    int oldCapacity = elementData.length;
    //扩容规则
    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
    elementData = Arrays.copyOf(elementData, newCapacity);
}

add(int, E):void

public void add(int index, E element) {
    //检查下标合法性
    rangeCheckForAdd(index);

    //是否需要扩容
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //将index后的元素往后移动一位
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;//元素数量加一
}

get(int):E

public E get(int index) {
    //检查下标合法性
    rangeCheck(index);

    return elementData(index);
}

remove(int):E

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    //元素数量减一,移除位置之后的元素向前移动一位
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

clear():void

public void clear() {
   modCount++;
    //将所有元素清空
    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

trimToSize():void

public void trimToSize() {
 modCount++;
     //数组容量依据当前实际大小进行收缩
    if (size < elementData.length) {
        elementData = Arrays.copyOf(elementData, size);
    }
}

总结

ArrayList实际就是依据数组来存储,与普通数组最大不同在于ArrayList可以动态伸缩,原理就是依靠System类内部的arraycopy方法。整体代码很简单,基本就是对数组的常规操作。

你可能感兴趣的:(Java源码分析)