ArrayList的源码分析

2023-06-28,,

/**

  • Default initial capacity.
  • 初始化容量为10
    */
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    /**
  • Shared empty array instance used for default sized empty instances. We
  • distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
  • first element is added.
  • */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    /**

  • The array buffer into which the elements of the ArrayList are stored.
  • The capacity of the ArrayList is the length of this array buffer. Any
  • empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
  • will be expanded to DEFAULT_CAPACITY when the first element is added.
    */
    transient Object[] elementData; // non-private to simplify nested class access
    /**
  • The size of the ArrayList (the number of elements it contains).
  • @serial
    */
    private int size;
    //最大数组大小
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    //默认实例为一个空数组
    public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    //添加元素
    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 void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    //超过扩容
    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 = Arrays.copyOf(elementData, newCapacity);
    }
    //循环清除
    public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    
    size = 0;

    }
    //删除 --很巧妙的删除
    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;

    }