0

我在 for(Entry...) 循环中遇到错误,在调用 dfs() 后,它会显示 concurrentmodificationexception。即使visitedOrder 与foreach 循环无关,我也不知道为什么会发生这种情况。如何解决这个问题?

public TreeMap<Integer, Integer> DFS()
{
    TreeMap<Integer, Integer> stack = new TreeMap<Integer, Integer>();
    TreeMap<Integer, Integer> visitedOrder = stack;
    for(int i = 1; i < graph[0].length-1; i++)
    {
        stack.put(i, 0);
    }
    for(Entry<Integer, Integer> vertex : stack.entrySet())
    {
        if(vertex.getValue() == 0)
            dfs(vertex.getKey(), visitedOrder);
    }
    System.out.println(visitedOrder.values());
    return visitedOrder;
}

public void dfs(int vertex, TreeMap<Integer, Integer> visited)
{
    visited.put(vertex, order++);
    int currVertex = vertex;
    for(int i = vertex; i < graph[0].length-1;i++)
    {
        if(graph[vertex][i+1] == 1)
        {
            dfs(++currVertex, visited);
            break;
        }
        currVertex++;
    }
}
4

3 回答 3

2

这是“Class ConcurrentModificationException”的 Javadoc:

当这种修改是不允许的时,检测到对象的并发修改的方法可能会抛出此异常。

例如,通常不允许一个线程在另一个线程对其进行迭代时修改 Collection。一般来说,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些迭代器实现(包括 JRE 提供的所有通用集合实现的那些)可能会选择抛出此异常。这样做的迭代器被称为快速失败迭代器,因为它们快速而干净地失败,而不是在未来不确定的时间冒着任意的、非确定性的行为的风险。

请注意,此异常并不总是表示对象已被不同的线程同时修改。如果单个线程发出一系列违反对象约定的方法调用,则该对象可能会抛出此异常。例如,如果线程在使用快速失败迭代器迭代集合时直接修改了集合,则迭代器将抛出此异常。

碰巧,这正是您正在做的事情:修改您在“foreach”循环中使用的结构。

解决方法:

如果你认为你的设计是正确的,那么替换一个简单的 for 循环:for (int i=0; i < myContainer.size(); i++) ...

于 2013-03-06T04:20:12.247 回答
1

即使visitedOrder 与foreach 循环无关,我也不知道为什么会发生这种情况。

您正在尝试修改TreeMap阅读时的内容。您只是在此行中指向此处的参考。所以它只是具有不同参考名称的相同 TreeMap。

    TreeMap<Integer, Integer> stack = new TreeMap<Integer, Integer>();
    TreeMap<Integer, Integer> visitedOrder = stack;
于 2013-03-06T04:16:52.670 回答
0

TreeMap执行new TreeMap<Integer, Integer>(). stack变量引用这个实例;该visitedOrder变量也引用同一个实例。当你调用 时dfs(int vertex, TreeMap<Integer, Integer> visited)visited参数也引用同一个TreeMap实例。

现在您正在循环中迭代此TreeMap实例的条目集for(Entry<Integer,...。迭代时,您调用该dfs(int, TreeMap<Interge, Integer>)方法,并在此方法中调用实例put上的aTreeMap并修改实例;因此ConcurrentModificationException.

根据您提供的代码,我的理解是您正在尝试通过执行 DFS将graph数组转换为 a 。TreeMap您正在遍历TreeMap引用的 bystack并尝试填充visitedOrder. 要解决您遇到的异常,只需将visitedorder变量指向一个new TreeMap<Integer, Integer>()实例。

请注意,我建议的修复旨在修复异常,同时保持代码流和逻辑不变,因为我对您的解决方案只有有限的了解。

于 2013-03-06T05:41:17.937 回答