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

Java List 遍歷中動態新增元素?用 for 迴圈替代 Iterator 避免 ConcurrentModificationException

     編輯:程式設計綜合問答

在遍歷 CopyOnWriteArrayList 時嘗試向同一列表新增元素,導致邏輯錯誤或例外。本文揭示根因並給出正確的遞迴式遍歷寫法。

問題代碼剖析

Iterator<Long> iterator = supList.iterator();
while (iterator.hasNext()) {
    Long s = iterator.next();
    for (OrgDto o : list) {
        if (o.getOrgId().equals(s) || o.getSupOrgId().equals(s)) {
            nameList.add(o.getOrgName().trim());
            supList.add(o.getOrgId()); // 修改正在遍歷的列表
        }
    }
}

CopyOnWriteArrayList 的迭代器是快照式的,遍歷過程中新增的元素不會被當前迭代器看到,導致遞迴查找子部門失效。

正確解法:索引式 for 迴圈

for (int i = 0; i < supList.size(); i++) {
    Long s = supList.get(i);
    for (OrgDto o : list) {
        if (o.getOrgId().equals(s) || o.getSupOrgId().equals(s)) {
            nameList.add(o.getOrgName().trim());
            if (o.getSupOrgId().equals(s)) {
                supList.add(o.getOrgId()); // 動態擴展,for 迴圈能感知 size 變化
            }
        }
    }
}

為什麼這樣可行?

  • for (int i=0; i<list.size(); i++) 每次迴圈都重新讀取 size(),新增元素會被後續迴圈處理。
  • 避免了 ConcurrentModificationException,同時實現了「廣度優先」的部門樹遞迴查找。

輸出結果

正確輸出:10部門、12部門、13部門 —— 完整包含父部門及所有子孫部門。

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