// 每次都會計算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);
}
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);
}
Iterator的定義代碼
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異常。