java ArrayList.add方法一共有两种方式,如下代码:
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);//第一种,顺序在末尾添加元素
arr.add(0,2);//第二种,在指定位置添加元素
System.out.println(arr);
第一种是添加在末尾,第二种是添加在指定位置
我们分别来看下这两种方法底层是怎么实现的
第一种:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
第一种方式十分的简单,先用ensureCapacityInternal()方法增加list长度实现,然后把新的元素放到末尾
第二种:
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++;
}
第二种方式先用rangeCheckForAdd()方法查看的index的合法性,大于list.size的和小于0,则会报错数组越界,代码如下
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
判断完index的合法性之后,然后用ensureCapacityInternal()方法扩容
之后使用System.arraycopy()方法对list进行操作
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
src:源数组(被操作的数组);
srcPos:源数组要复制的起始位置(从源数组的什么位置开始复制);
dest:目的数组(要复制到的那个数组);
destPos:目的数组放置的起始位置(从哪个元素开始覆盖);
length:复制的长度(复制多少位);
//例:
//数组1:
int[] arr1 = { 1, 2, 3, 4, 5 };
//数组2:
int[] arr2 = { 6, 7, 8, 9, 10 };
//运行:
System.arraycopy(arr, 1, arr2, 0, 2);
意思就是复制arr1的下标1位置开始往后的两个元素[2, 3],然后替换arr2中的下标0位置开始,往后的两个元素[6, 7],最后运行的的结果是:{2,3,8,9,10}
这个方法同样可以实现自己到自己的拷贝,也就是ArrayList.add往中间插入的方法用到的用法
//例:
//数组: //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};
这时候我们再来看下ArrayList.add方法,就十分的清晰了
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++;
}