標籤:
測試代碼為:
public static void main(String[] args) {List<String> strList = new ArrayList<String>();strList.add("1");strList.add("2");strList.add("3");strList.add("4");for(String str:strList){if(str.equals("4")){strList.remove(str);}}}
運行後結果如下:
跟蹤代碼,拋出異常的地方具體在:
public E next() { checkForComodification(); try {E next = get(cursor);lastRet = cursor++;return next; } catch (IndexOutOfBoundsException e) {checkForComodification();throw new NoSuchElementException(); }}
遍曆時返回一個元素之前,會調用checkForComodification()函數進行檢查,該函數實現為:
final void checkForComodification() { if (modCount != expectedModCount)throw new ConcurrentModificationException();}
modCount 為ArrayList修改的次數,expectedModCount 為期望修改的次數,在刪除第四個元素之前,modCount 和expectedModCount 均為4,而調用ArrayList的remove()方法後,modCount 變為5,但expectedModCount 仍為4,因此出現上述異常。
解決方案為:使用 Iterator的remove()方法取代ArrayList的remove()方法,可以避免ConcurrentModificationException異常。
巧合的是,如果要刪除的元素正好是集合中倒數第二個元素,則不會拋出此異常。Iterator遍曆擷取一個元素之前會先調用hasNext()方法來判斷是否還有元素,該方法實現為:
public boolean hasNext() { return cursor != size();}
其中cursor為遍曆的位置,從0開始,在上面的next()方法中更新。
刪除元素"3"後,cursor的值為3,而size()也返回3,hasNext()返回false,就不會調用next()方法了,因此也不存在ConcurrentModificationException異常。
刪除元素"4"後,cursor的值變為4,而size()返回3,hasNext()返回true,調用next()方法時就會拋出ConcurrentModificationException異常。
附上一篇資料:
Java ConcurrentModificationException異常原因和解決方案:http://www.cnblogs.com/dolphin0520/p/3933551.html
java修改集合拋出ConcurrentModificationException異常