// 每次都会计算list.size()比较耗费性能 public static void remove1 (List < String > list, String target){ for (int i = list.size() - 1; i >= 0; i--) { String item = list.get(i); if (target.equals(item)) { list.remove(item); } } print(list); }
//通过 CopyOnWriteArrayList 解决了 List的并发问题。每次remove的都是复制出的list public static void remove2 (ArrayList < String > list, String target){ final CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<String>(list); for (String item : cowList) { if (item.equals(target)) { cowList.remove(item); } } print(cowList); }
Iterator的定义代码
public static void remove3 (List < String > list, String target){ Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String item = iter.next(); if (item.equals(target)) { iter.remove(); } } print(list); }
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
通过代码我们发现 Itr 是 ArrayList 中定义的一个私有内部类,
在 next、remove方法中都会调用 checkForComodification 方法,该方法的作用是判断 modCount != expectedModCount是否相等,如果不相等则抛出ConcurrentModificationException异常。
每次正常执行 remove 方法后,都会对执行expectedModCount = modCount赋值,保证两个值相等,那么问题基本上已经清晰了,在 foreach 循环中执行 list.remove(item);,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改,因此抛出了ConcurrentModificationException异常。