In the Java language, ArrayList is an implementation of the List interface. It is usually used as a dynamic array of variable length. ArrayList is a non-thread-safe class. In a concurrent environment, multiple threads operating on ArrayList at the same time can cause unpredictable errors.

1. Construction method

ArrayList has two constructors, one that takes no arguments and the other that requires an initial capacity value. The most commonly used constructor is the no-argument constructor. The code is as follows:

private static final int DEFAULT_CAPACITY = 10; // The initial capacity is 10
private static final Object[] EMPTY_ELEMENTDATA = {};// An empty object
// An empty object. If created using the default constructor, the default object content defaults to this value
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData; // Where the current data object is stored. The current object does not participate in serialization
private int size; // The current array length
 
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); }}public ArrayList(a) {
   this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
Copy the code

What both constructors do is not that complicated; both aim to initialize the underlying array elementData. The difference is that the no-argument constructor initializes an empty array of elementData, and when elements are inserted, expansion reinitializes the array with the default values. The parameterized constructor initializes elementData as an array of parameter values (>= 0).

2. Capacity expansion mechanism

For variable-length data structures, expansion is required when there is no free space available in the structure. In an ArrayList, when space runs out, it expands by 1.5 times the size of the original array.

3. Manually reduce capacity

After inserting a lot of elements into an ArrayList and deleting a lot of elements, the underlying array has a lot of free space. Because ArrayList has no automatic scaling mechanism, a large amount of free space in the underlying array cannot be freed, resulting in waste. ArrayList also provides a way to handle this, as follows:

/** Reduces the array size to the number of elements */
public void trimToSize(a) {
   modCount++;
   if (size < elementData.length) {
       elementData = (size == 0)? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); }}Copy the code

Using the above method, we can manually trigger the scaling mechanism for ArrayList. This will free up excess space and improve space utilization.