privatevoidrangeCheckForAdd(int index){ // 索引不能大于ArrayList的size,并且不能小于0 if (index > size || index < 0) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); }
调用add(int index, E element)效率并不高,每次add一个元素,都要移动该元素后面的所有元素。最坏的情况下时间复杂度是O(n)
remove方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public E remove(int index){ // 检查索引越界 rangeCheck(index); // 记录修改次数 modCount++; // 获取要被删除的元素,准备在方法结束时返回给调用者 E oldValue = elementData(index); // 这里做了一个判断,如果删除的不是最后一个元素,则需要将index后的元素向前移动 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 将最后一个元素位置置为null,便于GC回收 elementData[--size] = null; // clear to let GC do its work return oldValue; }
与add(int index, E element)类似,如果从中间删除时,数组会将index后的元素统一向前移动。
publicbooleanremove(Object o){ if (o == null) { // 如果对象是null,则找到第一个null元素的索引,并从数组中删除,查找方式是从前到后 for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { // 如果对象不是null,则找到对象的索引,从数组中删除,查找方式也是从前到后 for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
privatevoidfastRemove(int index){ // 记录数组操作次数 modCount++; // 如果删除的元素不在数组尾部,则需要向前移动数组 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 最后以为元素设置为null,便于GC回收 elementData[--size] = null; // clear to let GC do its work }
publicintindexOf(Object o){ // 从前到后查找 if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
publicintlastIndexOf(Object o){ // 从后到前查找 if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData[i]==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData[i])) return i; } return -1; }