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

Java ArrayList 迭代時安全刪除元素的正確姿勢

     編輯:Java 相關知識

前言

在實際開發中,我們經常需要在遍歷 ArrayList 時動態移除符合條件的元素。乍看之下似乎很直觀,但若不當處理極易拋出 IndexOutOfBoundsException。本文將分析錯誤成因,並提供兩種正確且推薦的解決方案。

錯誤示範:直接在 for 迴圈中 remove

for (int i = 0, len = list.size(); i < len; ++i) {
    if (list.get(i) == XXX) {
        list.remove(i); // 危險!
    }
}

執行結果會拋出異常:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
    at java.util.ArrayList.rangeCheck(ArrayList.java:657)
    at java.util.ArrayList.get(ArrayList.java:433)
    ...

原因分析

remove(i) 會導致後續元素前移,索引變小,但迴圈變數 i 仍持續遞增,且 len 未更新。當遍歷到尾部時,實際集合大小已小於原始 len,導致 get(i) 索引越界。

修正方案一:手動維護索引與長度

for (int i = 0, len = list.size(); i < len; ++i) {
    if (list.get(i) == XXX) {
        list.remove(i);
        --len; // 關鍵:同步縮減預期長度
    }
}

雖然可行,但程式碼較繁瑣,且易因漏改 len 而埋下隱患。

推薦方案二:使用 Iterator 介面(標準做法)

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String e = it.next();
    if (e.equals("3")) {
        it.remove(); // 安全移除當前元素
    }
}

為何推薦 Iterator?

  • 封裝性佳:List 內部實作了 Iterator,remove() 由 JDK 保證線程安全與索引一致性。
  • 原始碼佐證:查看 ArrayList 原始碼可發現,許多方法(如 removeAll、retainAll)底層均委託給 Iterator 實作。
  • 語意清晰:明確表達「遍歷並條件式刪除」的意圖,減少認知負擔。

總結

遍歷集合時需刪除元素,請優先使用 Iterator 的 remove() 方法。若效能極度敏感且集合較小,手動調整索引長度亦可接受,但維護成本較高。切記:絕不可在 for-each 或傳統 for 迴圈中直接呼叫集合的 remove()。

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