[Source] ArrayList add method (automatic expansion)

1 add source code parsing

In the [Code] ArrayList ArrayList constructor in, ArrayList default constructor with no arguments is an empty array, but the capacity of said annotation array 10. In fact, the capacity of ArrayList add method is invoked when the initialization. add method is a common method List declared in the interface. ArrayList add the source as follows:

/**
     * Appends the specified element to the end of this list.
     *添加指定元素到这个列表中
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

size is the current number of elements in the set has (not capacity size, counted and no new elements prepared). In the call for ArrayList add method ensureCapacityInternal for expansion, size + 1 is to ensure that new entrants elements to meet the requirements. Next, look ensureCapacityInternal method:

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//#1
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//#2
        }

        ensureExplicitCapacity(minCapacity);//#3
    }
  • Line # 1 elementData determines whether an empty array (0 is the initial capacity, call the constructor with no arguments or functions), if yes, performing row # 2
  • Line # 2 and the selection between minCapacity DEFAULT_CAPACITY a relatively large value. Wherein DEFAULT_CAPACITY is a static constant value of 10
 /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;
  • # 3 performs row of ensureExplicitCapacity method source code as follows:
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)//#1
            grow(minCapacity);//#2
    }
  • The first line # 1, if the passed in elementData larger than the capacity (capacity here, the number of elements which is not Element), row # 2 is performed.
  • The second line # 2, calls grow method, source grow method is as follows:
   /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//#1
        int newCapacity = oldCapacity + (oldCapacity >> 1);//#2
        if (newCapacity - minCapacity < 0)//#3
            newCapacity = minCapacity;//#4
        if (newCapacity - MAX_ARRAY_SIZE > 0)//#5
            newCapacity = hugeCapacity(minCapacity);//#6
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//#7
    }

  • The first line # 1, the pre-expansion elementData array capacity assigned to oldCapacity
  • The first line # 2, the oldCapacity right one, then add oldCapacity, and finally assigned to newCapacity. The expansion is 1.5 times oldCapacity assigned to newCapacity.
  • The first line # 3, if after capacity expansion newCapacity than the incoming parameters minCapacity also biography, then used directly minCapacity. This happens in the case of empty ArrayList capacity, i.e. oldCapacity = 0, when 1 minCapacity =.
  • # 5 If the first line of the new capacity expansion is greater than MAX_ARRAY_SIZE, then call hugeCapacity method to newCapacity assignment. MAX_ARRAY_SIZE initialized as follows:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

hugeCapacity source code as follows:

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

Source code is very simple, if minCapacity less than 0, an exception is thrown; otherwise, if minCapacity greater than MAX_ARRAY_SIZE, returns Integer.MAX_VALUE otherwise MAX_ARRAY_SIZE

  • # 6 The first line calls Arrays.copyof method that copy to a large array of new capacity of the original array.

2 empty constructor ArrayList as an example to explain the expansion process

Declare and create ArrayList object

ArrayList<String> list = new ArrayList();

We will call the empty constructor ArrayList

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

In the constructor will elementData of air (the array element is stored ArrayList) initializing an empty Object array, DEFAULTCAPACITY_EMPTY_ELEMENTDATA initialized as follows:

  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

Call the add method, automatic expansion

list.add("ceshi")

add source code as follows:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

Called here ensureCapacityInternal expansion, size refers to the number of elements in elementData (not capacity), size + 1 to be added to ensure that the elements are also able to meet e. After the completion of the expansion capacity, added to the e elementData array element, and returns true. Then take a look ensureCapacityInternal method:

   private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

Analyzing elementData is not an empty array, it is clear that an empty array, it is more DEFAULT_CAPACITY (value 10) and be minCapacity (value 1) and the size of the relatively large value is assigned to be minCapacity, so the final minCapacity = 10. Then call ensureExplicitCapacity method.

   private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

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

be minCapacity (value 10) minus elementData.length (value 0) must be greater than 0, the method performs grow

	private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//oldCapacity = 0
        int newCapacity = oldCapacity + (oldCapacity >> 1);// newCapacity = 0;
        if (newCapacity - minCapacity < 0)//#1
            newCapacity = minCapacity;//#2
        if (newCapacity - MAX_ARRAY_SIZE > 0)//#3
            newCapacity = hugeCapacity(minCapacity);//#4
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//#5
    }

As shown in Notes

  • Line # 1 newCapacity (value 0) is subtracted be minCapacity (value 10) is definitely smaller than 0, it will perform row # 2
  • Line # 2 newCapacity = 10;
  • The first line # 3 is certainly less than 0, it will not perform line # 4
  • The first line # 5, the empty array elementData expansion of the capacity of the array 10.

3 summary

  • ArrayList expansion is expansion when calling the add method
  • Empty constructor calls the ArrayList ArrayList initialization time, ArrayList will be initialized to an empty Object array
  • Empty constructor calls the ArrayList ArrayList initialization time, the expansion will add time to the default of 10 ArrayList
  • ArrayList each expansion capacity 1.5 times the current
Published 107 original articles · won praise 142 · views 130 000 +

Guess you like

Origin blog.csdn.net/u013293125/article/details/96112569