1. 程式人生 > >forearch迴圈時,不能使用add和remove不然會報錯

forearch迴圈時,不能使用add和remove不然會報錯

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。