ArrayList is the implementation class of the List interface

ArrayList collection features and source code analysis
ArrayList is the implementation class of the List interface

public class ArrayList<E> extends AbstractList<E>

    implements List<E>, RandomAccess, Cloneable,

It inherits the AbstractList class and implements Cloneable cloning interface, Serializable serialization interface, RandomAccess random access interface and List interface

Features: the bottom layer uses array to realize high query efficiency, slow addition and deletion, unsafe thread, allowed to be empty and repeatable

public static void main(String[] args) {

List<String> list=new ArrayList<String>();
boolean bool=list.add("ylc");//Adding elements to the Collection interface
list.add(1,"ww");//Add elements based on index
String el=list.get(1);//Get element by index
list.size();//Get the number of elements
list.remove(2);//Delete according to element location
list.remove("ylc");//Deletes the specified element
list.set(1,"yy");//Replace element
list.clear();//Empty collection
list.isEmpty();//Determine whether the element is empty
list.contains("ylc");//Determine whether the collection contains an element
list.indexOf("ylc");//Find the location in the file
list.lastIndexOf("ylc");//Index position of the last occurrence of the element
Object[] objects=list.toArray();//Convert a collection into an object array
for (int i = 0; i < objects.length; i++) {
    String str=(String) objects[i];
String[] strings=list.toArray(new String[list.size()]);//Converts the collection to an array of the specified type
List<String> list2=new ArrayList<String>();
list.addAll(list2);//Collection merge operation
list.retainAll(list2);//Set intersection operation list stores the intersection content
list.removeAll(list2);//Delete the elements in the list that contain the list2 collection

ArrayList source code analysis#
Member variable#
private static final int DEFAULT_CAPACITY = 10;// Array default length
private static final Object[] EMPTY_ELEMENTDATA = {};// Given an empty array
transient Object[] elementData;// Temporary arrays that store ArrayList elements are not saved to disk
private int size;// Record the number of elements in the array
protected transient int modCount = 0; // Identification of the number of modifications to the collection array (fail fast mechanism)
Transient keyword for fields that do not want to be serialized, use the transient keyword to modify

In JDK7, as long as an ArrayList array is created, an empty array with a length of 10 will be created by default.

In JDK8, a delayed loading is done. When creating an ArrayList array, an empty array with a length of 0 is created. Only when using this array will the length be changed, and a delayed loading is done

It contains three constructors

1. Parameterless constructor

When initializing an array, an empty array is assigned by default

//Parameterless constructor
public ArrayList() {

    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//The default is 0


2. Constructor of type int

If the passed in value is greater than 0, an array with the specified capacity will be created. If the value is 0, it is an empty object array. Otherwise, an exception will be thrown

//Constructor with capacity size

public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;//Empty object array
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+

3. Set type constructor

Turn the incoming collection into an array and assign it to elementData

The collection is not empty. If the incoming array type is changed to object, it is assigned to elementData

Otherwise, it is copied directly to elementData

public ArrayList(Collection<? extends E> c) {
    Object[] a = c.toArray();//Become an array
    if ((size = a.length) != 0) {//If the collection is not empty
        if (c.getClass() == ArrayList.class) {//Judge whether it is consistent with the ArrayList type
            elementData = a;//assignment
        } else {
            elementData = Arrays.copyOf(a, size, Object[].class);//Otherwise, copy directly to the array
    } else {
        elementData = EMPTY_ELEMENTDATA;//Set to empty array

Increase method#
Add (E) method#
public boolean add(E e) {

    ensureCapacityInternal(size + 1); //When size=0
    elementData[size++] = e;//Size is still 0. Assign a value to the size of 0
    return true;

//Ensure the internal capacity of the collection array
private void ensureCapacityInternal(int minCapacity) {//1

    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//Return 10

//Ensure explicit capacity
private void ensureExplicitCapacity(int minCapacity) {//minCapacity=10

    if (minCapacity - elementData.length > 0)// 10-0 > 0 determines the key code for capacity expansion. When the 11th array is added, execute the grow th Code

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

//Calculate array capacity
private static int calculateCapacity(Object[] elementData, int minCapacity) {

    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//0=0
        return Math.max(DEFAULT_CAPACITY, minCapacity);// DEFAULT_CAPACITY=10, minCapacity=1 returns the maximum value as the array capacity
    return minCapacity;

//Capacity expansion method
private void grow(int minCapacity) {

    int oldCapacity = elementData.length;//0
    int newCapacity = oldCapacity + (oldCapacity >> 1); //The array length plus the displacement operation (half of the array length) increases by 1.5 times each expansion, 0 = 0 + 0
    if (newCapacity - minCapacity < 0)//0-10<0
        newCapacity = minCapacity; //newCapacity=0
    if (newCapacity - MAX_ARRAY_SIZE > 0)//10-MAX_ARRAY_SIZE<0
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);//The copy operation copies a length of 10 into an empty array and generates a new length of 10 empty array

Size is 0 by default. The add method adds 1 to size and passes in the ensureCapacityInternal method. In the ensureCapacityInternal method, the ensureExplicitCapacity method is called and two parameters are passed in. The first is elementData, which represents an empty array, and the second is the number of arrays. In the calculateCapacity method, there is an if judgment. If the array size is equal to the default size, the maximum value will be returned. If the default array size is 10, default_ Capability is also equal to 10, so 10 is returned. Pass 10 into the ensureExplicitCapacity method, and then 10 into the grow th method to generate a new empty array with a length of 10. Finished executing the ensureCapacityInternal method. The size of the add method is still 0, assign a value to the index with subscript 0, and add a new one successfully.

Capacity expansion simulation

When the 11th element is added, the add method Size=10+1=11, passes in the ensureCapacityInternal method, and enters the calculateCapacity method. At this time, elementData=10 and defaultcapability_ EMPTY_ Elementdata = 0. If it is not satisfied, directly return minCapacity=11. The value 11 enters the ensureExplicitCapacity method. If it is satisfied that 11-10 > 0 enters the growth method, the growth method assigns the displacement one bit operation of oldCapacity=10 and newCapacity=10+10 = 10 + 5 = 15. Finally, use the copyOf method to expand the original 10 large and small arrays to 15.

add(int index, E element) method#
public void add(int index, E element) {

ensureCapacityInternal(size + 1); //Collection increase capacity
//elementData: original array index: copy from the index of the original array elementData: target array index + 1: the first element of the target array size-index: copy size index elements
System.arraycopy(elementData, index, elementData, index + 1,
                 size - index);
elementData[index] = element;//Replace all current arrays
size++;//Index increase

//Judge whether the index is out of bounds
private void rangeCheckForAdd(int index) {

    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

In this way, every time an element is added, the current index will be copied to the back of the element, which is very expensive

Posted on Sun, 31 Oct 2021 22:27:53 -0400 by Courbois