private void grow(int minCapacity) {//传参为最小需要扩容的大小 // overflow-conscious code int oldCapacity = elementData.length;//原有容量 int newCapacity = oldCapacity + (oldCapacity >> 1);//新容量为原容量的1.5倍 if (newCapacity - minCapacity < 0)//如果新容量(1.5倍)小于最小需要容量(原因:int取值范围越界) newCapacity = minCapacity;//赋值为最小所需容量 if (newCapacity - MAX_ARRAY_SIZE > 0)//如果新容量大于int最大值-8 newCapacity = hugeCapacity(minCapacity);//则利用hugeCapacity进行计算复制大小(后面有写) // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity);//分配好新空间,可以对旧数组进行扩容 }
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow 溢出 throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE ://最小分配大小大于Integer_Max-8则复制为int最大值 MAX_ARRAY_SIZE; }
public E remove(int index) { rangeCheck(index);//检查index越界
modCount++;//标记修改次数,类似版本号 E oldValue = elementData(index);//取出index位置的元素
int numMoved = size - index - 1;//需要移动元素的个数,也就是如果从index位置删除元素,那么后续所有其他元素需要前移一位来补空缺 if (numMoved > 0)//如果移动的元素不是最后一个元素,则都需要前移后面所有元素,由此可见,如果移除index=0的元素的效率最差,需要数组整体前移 System.arraycopy(elementData, index+1, elementData, index, numMoved);//移动操作 elementData[--size] = null; // clear to let GC do its work,将最后一个元素位置置为null,原注释解释方便GC回收垃圾
public boolean remove(Object o) { if (o == null) {//如果要移除元素为null for (int index = 0; index < size; index++) if (elementData[index] == null) {遍历查找数值=null的元素 fastRemove(index);//实际就是封装了之前移除过程 return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) {//使用equals来进行比较,如果相等,则移除 fastRemove(index); return true; } } return false; }
//此方法基本上就是对于之前移除过程进行封装,可参考public E remove(int index)中的移除注释 private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
public Iterator<E> iterator() {//默认调用此方法 return listIterator();//其中会调用listIterator(0),也就是从0位置开始迭代 }
public ListIterator<E> listIterator(final int index) { checkForComodification();//检测修改版本号,for concurrent rangeCheckForAdd(index);//检测越界 final int offset = this.offset;
return new ListIterator<E>() { int cursor = index;//内部维护索引,默认为0开始 int lastRet = -1;//记录上一次返回的索引,初始化为-1 int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {//是否有下一个元素 //这里使用sublist,实际上内部有属性指向parent(当前list),可理解为就是当前list return cursor != SubList.this.size;//判断游标是否到达list的size
}
@SuppressWarnings("unchecked") public E next() { checkForComodification();//检查修改次数版本号 int i = cursor; if (i >= SubList.this.size)//如果越界,抛出无元素异常 throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData;//创建对list的引用 if (offset + i >= elementData.length)//越界 throw new ConcurrentModificationException(); cursor = i + 1;//此时游标自动后移,为了迭代继续进行 return (E) elementData[offset + (lastRet = i)];//返回通过游标取出的元素,更新lastRet为当前返回的索引 }
public boolean hasPrevious() {//如果游标不等于0,则有前置元素 return cursor != 0; }
@SuppressWarnings("unchecked") public E previous() {//返回前置元素,与next方法大同小异 checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[offset + (lastRet = i)]; }
@SuppressWarnings("unchecked")//支持lambda表达式特性的方法 public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = SubList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (offset + i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[offset + (i++)]); } // update once at end of iteration to reduce heap write traffic lastRet = cursor = i; checkForComodification(); }
public int nextIndex() {//返回游标下一次访问的元素位置 return cursor; }
public int previousIndex() {//返回上一个访问的位置 return cursor - 1; }
public void remove() {//移除元素 if (lastRet < 0) throw new IllegalStateException(); checkForComodification();//同上
try { int i = cursor; SubList.this.add(i, e);//在当前游标位置添加元素 cursor = i + 1;//游标后移一位 lastRet = -1; expectedModCount = ArrayList.this.modCount;//设置期望的修改版本号,此处运用了类似CAS的控制机制,在许多方法调用前会有checkForComodification()方法来进行修改版本号检测 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
final void checkForComodification() {//修改版本号检测 if (expectedModCount != ArrayList.this.modCount) //这里使用了期望修改版本号与当前修改版本号对比,来判断是否期间有其他线程修改了这个值,利用CAS机制,以支持并发操作;如果不一致抛出并发修改异常 throw new ConcurrentModificationException(); } }; }
get and set:简单的获取元素和设置元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public E get(int index) { rangeCheck(index);//检查越界
return elementData(index);//直接返回元素 }
public E set(int index, E element) { rangeCheck(index);//检查越界
E oldValue = elementData(index);//记录index位置的旧元素 elementData[index] = element;//将index位置设置为新元素 return oldValue;//返回旧元素 }