说一下最简单的add操作 源码461行:
add一个泛型e元素的时候,会先调用ensureCapacityInternal方法,传入参数为当前数组长度+1。我们再来看看这个方法干了什么:
调用了一下ensureExplicitCapacity方法,参数为调用calculateCapacity方法的返回值。我们主要看一下作者对这两个方法的实现:
首先看一下calculateCapacity方法,该方法返回更新后的数组容量,传入的是现有的数组和+1的size(size为当前数组的长度),首先判断一下当前的Object数组是否是空数组,是空数组的话就就调用一下math方法判断一下10和+1的size谁大谁小,如果10>=minCapacity则返回10,否则返回minCapacity。如果不是空数组直接返回minCapacity。然后将返回的数据当作参数传到ensureExplicitCapacity方法中,modCount++是为了记录一下集合修改的次数,防止在用迭代器迭代集合时出现并发修改异常。然后判断一下minCapacity和数组的长度,如果minCapacity大于当前数组元素的长度,那么就调用一下grow方法来增加数组容量。后面的判断就不说了,最后copy一下这个数组再赋给原来的数组。
//grow方法的核心代码
int newCapacity = oldCapacity + (oldCapacity >> 1);//核心代码 (" >> 1 "表示将oldCapacity往右移一位,相当于oldCapacity/2,最终的newCapacity约为原来数组长度的1.5倍)
Math的max方法的源码:
remove:只说一下最简单的remove(int index)方法
/** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). * * @param index the index of the element to be removed * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { rangeCheck(index);//该方法判断一下index参数是否小于或等于当前数组的size modCount++;//记录次数 E oldValue = elementData(index);//调用该方法,返回待删除的元素/index位置的元素 int numMoved = size - index - 1; if (numMoved > 0)//说明删除的不是数组中最后一个元素 System.arraycopy(elementData, index+1, elementData, index, numMoved);//调用本地方法arraycopy方法copy一下数组,将待删除的index位置的元素之后的元素整体向前移动一个位置
elementData[--size] = null; // clear to let GC do its work return oldValue; }//将数组的长度--
private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } E elementData(int index) { return (E) elementData[index]; }
总结:
add操作:
jdk1.8版本
1.首先在calculateCapacity方法中判断一下当前的Object数组是否是空数组,是空数组的话就就调用一下math方法判断一下10和+1的size谁大谁小,如果10>=minCapacity则返回10,否则返回minCapacity。如果不是空数组直接返回minCapacity
2.根据calculateCapacity方法返回的值,然后判断一下这个值和数组的长度,如果大于当前数组元素的长度,那么就调用一下grow方法来增加数组容量,增加的大约是原来数组长度的1/2。
3.ArrayList数组add操作是在数组的末尾添加元素,ArrayList是无序的,也可以有序,看我们插入的数据是否是有序的,无序时插入和查询操作的时间复杂度为O(1),有序时插入的时间复杂度为O(n),查询为O(1)。ArrayList底层是由Object[]数组实现。
remove操作:
1.先判断一下index参数是否小于或等于当前数组的size,大于的话报错。
2.找出待删除的的元素
3.判断一下删除的元素是否是数组中的最后一个元素,是的话直接将该元素置为null且将数组的size-1,否则将该元素所在位置的后面的元素整体向前移动一个位置,最后也将最后一个元素置为null且将数组的size-1。
over~ 不忘初心,方得始终