首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ArrayList 迭代器刪除元素:ConcurrentModificationException 原因與正確姿勢

     編輯:程式設計綜合問答

錯誤代碼還原

Iterator it = list.iterator();
while (it.hasNext()) {
    Integer val = it.next();        // 獲取元素 1
    if (val == target) {
        it.next();                  // ❌ 再次調用 next() 導致指鈕前移
        list.remove(val);           // 直接操作集合觸發 fail-fast
    }
}

核心誤區

  1. it.next() 是「獲取並前移」:每次調用都會移動游標,上例中循環體內調用兩次,導致跳過元素甚至越界。
  2. 直接調用 list.remove() 破壞迭代器狀態:ArrayList 通過 modCount 實現 fail-fast,迭代器檢測到結構性修改拋出 ConcurrentModificationException。

正確寫法:使用迭代器自身的 remove()

Iterator it = list.iterator();
while (it.hasNext()) {
    Integer val = it.next();        // ① 獲取當前元素,游標後移
    if (val == target) {
        it.remove();                // ② 安全刪除,同步更新 modCount
    }
}

Java 8+ 更簡潔寫法

// 1. removeIf(內部使用迭代器,線程不安全場景首選)
list.removeIf(val -> val == target);

// 2. Stream 過濾生成新列表(函數式風格)
List filtered = list.stream()
    .filter(val -> val != target)
    .collect(Collectors.toList());

原理解析

  • Iterator.remove() 是唯一合法的在迭代過程中修改集合的方式,它會更新迭代器內部的 expectedModCount。
  • modCount 機制:集合結構變更時 modCount++,迭代器每次操作前比對 expectedModCount == modCount,不一致拋異常。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved