Analysis of the bottom layer of ArrayList.add method

The java ArrayList.add method has two methods, the following code:

ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);//第一种,顺序在末尾添加元素
arr.add(0,2);//第二种,在指定位置添加元素
System.out.println(arr);

The first is to add at the end, the second is to add at the specified position

Let's take a look at how the underlying layers of these two methods are implemented.


The first:

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

The first method is very simple, first use the ensureCapacityInternal() method to increase the length of the list, and then put the new element at the end


The second type:

public void add(int index, E element) {
    rangeCheckForAdd(index);//检查index合法性

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

The second way is to use the rangeCheckForAdd() method to check the validity of the index. If the sum of the index is greater than list.size and less than 0, an error will be reported that the array is out of bounds. The code is as follows

private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

After judging the validity of the index, use the ensureCapacityInternal() method to expand the capacity

Then use the System.arraycopy() method to operate on the list

public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

src: source array (array to be operated);

srcPos: The starting position of the source array to be copied (from what position in the source array to start copying);

dest: destination array (the array to be copied to);

destPos: the starting position of the destination array (from which element to start covering);

length: the length of the copy (how many bits to copy);

//例:
//数组1:
int[] arr1 = { 1, 2, 3, 4, 5 };
//数组2:
int[] arr2 = { 6, 7, 8, 9, 10 };
//运行:
System.arraycopy(arr, 1, arr2, 0, 2);

It means to copy the two elements [2, 3] after the subscript 1 of arr1, and then replace the two elements [6, 7] after the subscript 0 in arr2, and finally run the result is: {2,3,8,9,10}

This method can also implement self-to-self copying, which is the usage used by the method of inserting ArrayList.add into the middle

//例:
//数组: //ArrayList.add方法中先用ensureCapacityInternal进行了扩容,使得末尾空出一个null
object[] arr = { 1, 2, 3, 4, 5 ,6 ,7 ,8 ,null};
System.arraycopy(arr, 1, arr, 2, 7);
//这段代码的执行的结果为:{ 1,null, 2, 3, 4, 5 ,6 ,7 ,8};

At this time, let's look at the ArrayList.add method again, it is very clear

public void add(int index, E element) {
    rangeCheckForAdd(index);//检查index合法性

    ensureCapacityInternal(size + 1);  // 扩容
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);//把index位置空出来,给插入的元素留位置,后边的元素向后顺延一个
    elementData[index] = element;//在空位添加元素
    size++;
}

Guess you like

Origin blog.csdn.net/qq_38217990/article/details/128920973
Recommended