簡體   English   中英

遞歸遍歷樹時出現 ConcurrentModificationError

[英]ConcurrentModificationError when traversing a tree recursively

當遞歸遍歷樹結構以計算整個材料清單的重量和體積時,我遇到了 ConcurrentModificationException。 我的偽代碼方法:

  1. 查詢初始化:將根節點添加到節點列表中並檢查它是否有任何子節點。
  2. 進度文檔:將節點標記為已訪問。
  3. 查詢子節點:檢查子節點,如果存在,則使用升級標志添加到 allNodes。
  4. 遞歸遍歷:遞歸遍歷列表,直到找不到更多子元素。

我曾嘗試使用迭代器來允許自己擴展該節點數組,但遇到了同樣的問題。 在這里慢慢用完想法,我很感激任何提示。

注意:請原諒我粘貼我的問題,而不是說明所有上下文以提高可讀性。 如果您需要更多信息,請告訴我。

// Initialization
List<Node> allNodes = new ArrayList<>();
allNodes.add(new Node(input, input, 0, false)     // (1)
int counter = 0;

// Method call
getAllNodes(allNodes);

// Query parent for child elements
public void getAllNodes(List<Node> nodes){
    for (Node node : nodes) {   
        if (!node.isVisited()) {      // (2)
            node.setVisited(true);
            String parentId = node.getId();
            Product product = QueryUtil.getFirstByIdNo(ctx, parentId, Product.class);
            if (isComposite(product)) {
                Iterable<Product.Row> rows = product.table().getRows();   // (3)
                for (Product.Row row : rows) {
                    allNodes.add(new Node(parentId, row.getProductListElem().getIdno(), ++counter, false));
                    --counter;
                }
                ++counter;
               // Recursive query of all node elements
                getAllNodes(allNodes);        // (4)
            }
        } 
    }
}

//Node Bean with getters, setters, constructor, toString
@Data
class Node {
    String parent;
    String id; 
    int level;
    boolean visited;
}

您收到錯誤是因為您正在嘗試修改您正在迭代(閱讀)的列表。 而這在 JAVA 中是不允許的。 [更多解釋請點擊這里]

為避免這種情況,您可以為您的列表獲取一個迭代器,然后對其進行循環,但這對於您上面發布的代碼來說似乎不是一個很好的選擇。 因此,我建議使用List<Node> allNodes = new CopyOnWriteArrayList<>(); 而不是List<Node> allNodes = new ArrayList<>()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM