首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 集合遍歷刪除元素的正確姿勢:Iterator.remove() 避坑指南

     編輯:Java 程式設計入門

在 for-each 或 Iterator 遍歷 List 時直接呼叫 list.remove() 會拋出 ConcurrentModificationException。本文從錯誤示範出發,層層遞進到最佳實踐 Iterator.remove(),並補充 Java 8+ 的函數式寫法。

❌ 錯誤示範:遍歷中直接刪除

public void operate(List list) {
    for (Iterator it = list.iterator(); it.hasNext(); ) {
        String str = it.next();
        if ("chengang".equals(str)) {
            list.remove(str); // 拋出 ConcurrentModificationException
        }
    }
}

原因:ArrayList 內部維護 modCount,Iterator 快照 expectedModCount,結構性修改導致不一致檢查失敗。

⚠️ 笨拙但可行:雙列表法

public void operate(List list) {
    List toRemove = new ArrayList<>();
    for (String str : list) {
        if ("chengang".equals(str)) toRemove.add(str);
    }
    list.removeAll(toRemove);
}
  • 優點:邏輯直觀、無並發異常
  • 缺點:額外 O(n) 空間、兩次遍歷、程式碼冗長

✅ 最佳實踐:Iterator.remove()

public void operate(List list) {
    for (Iterator it = list.iterator(); it.hasNext(); ) {
        String str = it.next();
        if ("chengang".equals(str)) {
            it.remove(); // 安全刪除,同步更新 modCount
        }
    }
}

原理:Iterator.remove() 內部會同步更新 expectedModCount = modCount,避免檢查失敗。

🚀 Java 8+ 函數式寫法(更簡潔)

// 1. removeIf(原地修改,返回是否有刪除)
list.removeIf("chengang"::equals);

// 2. Stream 過濾產生新列表(不變原列表)
List filtered = list.stream()
                            .filter(s -> !"chengang".equals(s))
                            .collect(Collectors.toList());
方法修改原列表適用場景Java 版本
Iterator.remove()是需在循環中執行額外邏輯1.2+
removeIf(Predicate)是單純條件刪除,程式碼最少8+
Stream.filter()否(產生新列表)需保留原列表、鏈式操作8+

避坑檢查清單

  • ✅ 使用 Iterator 而非 for-each(後者隱藏 Iterator 無法呼叫 remove())
  • ✅ 僅呼叫 it.remove(),不可同時呼叫 list.remove()
  • ✅ 多執行緒環境下改用 CopyOnWriteArrayList 或加鎖
  • ✅ Java 8+ 優先考慮 removeIf()

總結

「代碼越簡潔,對基礎理解越深」。掌握 Iterator.remove() 與 removeIf(),讓集合刪除既安全又優雅。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved