preface

When you talk about An ArrayList, you focus on its auto-scaling mechanism, but most people don’t pay attention to whether an ArrayList automatically shrinks. Here’s how ArrayList shrinks based on a few questions.

PS: Scaling refers to the reduction in size of the Object array elementData in the ArrayList

ArrayListDoes the capacity shrink automatically?

Since the automatic scaling of an ArrayList usually happens in the add() and addAll() methods, does it automatically shrink when an ArrayList calls remove()?

ArrayList#remove()Source code analysis

There are two remove() methods

  1. The input argument to array subscript returns the deleted element
  2. Returns the array subscript for an array element

PS: The JDK source of this article is Oracle JDK 1.8

The source code for the first method is analyzed here

Public E remove (int index) {/ / check whether incoming subscript is greater than or equal to the length of the ArrayList size / / if more than direct selling IndexOutOfBoundsException rangeCheck (index);  // modCount is used for fast failure mechanism, modCount++ is not expanded; // Get the value of the element to be deleted E oldValue = elementData(index); Int numMoved = size-index - 1; int numMoved = size-index - 1;ifArraycopy (elementData, index+1, elementData, index, numMoved); ElementData [--size] = null; elementData[--size] = null; // Returns the value of the deleted elementreturn oldValue;
    }
Copy the code

PS: System# arrayCopy () does not affect the length of the source and destination arrays.

ArrayList#remove()Source schematic

If you find the source code confusing, see the key process diagram for the remove() method of ArrayList below

As you can see from the above, ArrayList does not actually reduce the size of the built-in Object array when it executes remove(). It simply removes parts of the array to the left, sets the last element to NULL, and decreases the size. The same applies to remove(), removeAll(), and removeRange() that return an array index as an array element.

ArrayList#clear()Source code analysis

In addition to remove(), ArrayList also has a clear() method that clears arrays. So how does it work? It’s actually so simple I can’t believe it

public void clear() {modCount++; // Set traversal groups to NULL to facilitate gc collectionfor(int i = 0; i < size; i++) elementData[i] = null; Size = 0; }Copy the code

conclusion

As you can see from the analysis of the above two sections of the source code, ArrayList does not actually provide automatic scaling. In fact, there is nothing wrong with such a design, after all, a lot of times can not judge whether the need to shrink the operation. Since it doesn’t shrink automatically, can ArrayList shrink automatically?

ArrayListCan it be reduced?

There is, of course, the trimToSize() method. This method shrinks the built-in array of ArrayList to its current size, and the source code is particularly simple: give elementData an array of the corresponding size. The source code is as follows

    public void trimToSize() {modCount++; // Determine whether the current capacity needs to be reducedif(size < elementData.length) {// If size is 0, assign the built-in empty array to elementData directly. // If size is not 0, create a new array of size length elementData = (size == 0)? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); }}Copy the code

conclusion

  1. ArrayListtheremoveIt just moves the array partially to the left and sets the last element tonullAt the same timesizeSubtract to delete. In fact, noelementDataShrink the capacity.
  2. You can usetrimToSize()The method ofelementDataShrink the capacity.