forearch迴圈時,不能使用add和remove不然會報錯
阿新 • • 發佈:2018-12-21
forearch迴圈注意事項
不要在 foreach 迴圈裡進行元素的 remove/add 操作。remove 元素請使用 Iterator 方式,如果併發操作,需要對 Iterator 物件加鎖。
正例: Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (刪除元素的條件) {
iterator. remove();
}
}
反例: List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}
說明:以上程式碼的執行結果肯定會出乎大家的意料,那麼試一下把“1”換成“2”,會是同樣的 結果嗎?
根本原因在於expectedModCount與modCount他們的不相等,由於執行了ArrayList中的remove(),modCount在每一次迴圈值會發生改變,而expectedModCount並沒有發生,在執行checkForComodification()方法就會丟擲異常。
在next()、remove()操作中都會進行 checkForComodification() ,用於檢查迭代期間其他執行緒是否修改了被迭代物件。下面是checkForComodification方法:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
這是一種 Fail-Fast(快速失敗) 策略,只要被迭代物件發生變更,將滿足 modCount != expectedModCount 條件,從而丟擲ConcurrentModificationException。