有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何解决数组列表中未知源的问题?

我需要得到树的一个节点的所有后代。为此,我编写了一个需要帮助的函数。当我想要得到结果时,我会得到以下错误:

在爪哇。base/java。util。ArrayList$Itr。CheckForComodition(未知源) 在爪哇。base/java。util。Itr$ArrayList。下一个(未知源)

我已经犯了这个错误,这就是为什么我为每个方法创建了不同的列表:子方法、子方法、祖先方法、元素和位置。现在我到处都有错误

public List<Position<E>> descendants(Position<E> p) throws InvalidPositionException {
    if(p == null || isEmpty())
            throw new InvalidPositionException();
    // remove all positions from list
    descendantList.removeAll(descendantList);
    return descendantsList(p);
}
public List<Position<E>> descendantsList(Position<E> p) {
    if(isInternal(p)) {
        // add child to list and check if the child has also children
        for(Position<E> child : children(p)) {
            descendantList.add(child);
            // if child has also children
            if(isInternal(child))
                descendantsList(child);
        }
    }
    return descendantList;
}

children函数如下所示:

public List<Position<E>> children(Position<E> p) throws InvalidPositionException {
    if(p == null || isEmpty())
        throw new InvalidPositionException();
    else {
        BinaryTreeNode<E> node = (BinaryTreeNode<E>) p;
        childrenList.removeAll(childrenList);
        // add left child first
        if(node.leftChild != null)
            childrenList.add(node.leftChild);
        if(node.rightChild != null)
            childrenList.add(node.rightChild);
        return childrenList;
    }
}

为此,我创建了不同的列表:

- ArrayList for children: childrenList
- ArrayList for descendants: descendantsList

如何解决此错误

编辑:我将所有removeAll替换为clear。它适用于此方法,但作为示例,我的高度方法仍然存在相同的错误:

public int height() throws EmptyTreeException {
    if(isEmpty())
        throw new EmptyTreeException();
    else
        return heightOf(root);
}
private int heightOf(Position<E> p) {
    if(isExternal(p))
        return 0;
    else {
        int h = 0;
        for(Position<E> child : children(p)) {
            h = Math.max(h,heightOf(child));
        }
        return h + 1;
    }
}

共 (2) 个答案

  1. # 1 楼答案

    不要使用removeAll(childrenList)。使用clear()。首先,它更快,其次,这可能是你得到错误的地方removeAll()逐步遍历提供的集合,并删除调用该集合的集合中的元素。在你的情况下,这是相同的集合

    编辑:好的。我知道发生了什么事。我必须亲自实施才能看到

    基本上,发生的是你调用height(root)。这将遍历树并查找每个节点的heightOf,然后返回该节点

    heightOf方法中,有一个使用递归的for循环

    for循环调用children(node),清除列表childrenList,然后重新填充它

    问题是在第一次迭代中childrenList被分配了一些值。然后再次调用heightOf,同时仍然引用位于childrenList中的Position<E>(您称之为Position<E>子级)。在子级上再次调用heightOf时,再次修改childrenList。由于您仍然在childrenList中持有对Position<E>的引用,并且您试图删除或更改此引用,因此您会得到一个ConcurrentModificationException

    您可以通过将children方法更改为以下内容来解决此问题:

    public List<Position<E>> children(Position<E> p) throws InvalidPositionException {
        List<Position<E>> returnList = new ArrayList<>();
        if(p == null || isEmpty()) {
            throw new InvalidPositionException();
        }else {
            BinaryTreeNode<E> node = (BinaryTreeNode<E>) p;
            // add left child first
            if(node.leftChild != null) {
                returnList.add(node.leftChild);
            }
            if(node.rightChild != null) {
                returnList.add(node.rightChild);
            }
            return returnList;
        }
    }
    

    为了维护树中所有节点的childrenList,您可能需要创建一个新方法并只调用该方法一次。该方法看起来与当前的children方法非常相似,但可以在每个节点的左、右子节点上递归调用它

  2. # 2 楼答案

    我是这样解决的: 我为每个使用子列表的方法创建了一个新列表。因此,我没有得到以下错误:

    在爪哇。base/java。util。ArrayList$Itr。检查java上的共修改(未知源代码)。base/java。util。ArrayList$Itr。下一个(未知源)