/** * 移除指定下标元素 */ public E remove(int index){ rangeCheck(index); //修改次数+1 modCount++; E oldValue = elementData(index); //需要重排的数据个数 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
return oldValue; }
/** * 移除指定元素 */ publicbooleanremove(Object o){ if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; } privatevoidfastRemove(int index){ //修改次数+1 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 E get(int index){ checkElementIndex(index); return node(index).item; } Node<E> node(int index){ //索引小于1/2,则查左一半,否则查右一半 if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } //获取首节点元素 public E getFirst(){ final Node<E> f = first; if (f == null) thrownew NoSuchElementException(); return f.item; } //获取性节点元素 public E getLast(){ final Node<E> l = last; if (l == null) thrownew NoSuchElementException(); return l.item; }
publicstaticvoidmain(String[] args){ List<String> list = new ArrayList<>(); list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); for (String s : list) { if ("bb".equals(s)) { list.remove(s); } } System.out.println(list); }
我们预计会输出包含 aa, bb, cc 的值,但是实际呢?
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
publicstaticvoidmain(String[] args){ List<String> list = new ArrayList(); list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); Iterator var2 = list.iterator(); while(var2.hasNext()) { String s = (String)var2.next(); if("bb".equals(s)) { list.remove(s); } } System.out.println(list); }
实际 for(a:b) 只是个语法糖,用的还是迭代器。我们进入到迭代器,查看 next() 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int expectedModCount = modCount; public E next(){ //校验修改 checkForComodification(); int i = cursor; if (i >= size) thrownew NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) thrownew ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; }
finalvoidcheckForComodification(){ //modCount不对的话,会抛异常 if (modCount != expectedModCount) thrownew ConcurrentModificationException(); }
publicstaticvoidmain(String[] args){ List<String> list = new ArrayList<>(); list.add("aa"); list.add("bb"); list.add("cc"); list.add("dd"); for (int i = 0; i < list.size(); i++) { if ("bb".equals(list.get(i))) { list.remove(i); } } System.out.println(list); }