0

for(Entry ...)ループでエラーが発生し、dfs()を呼び出した後、concurrentmodificationexceptionと表示されます。visitOrderが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

「クラス ConcurrentModificationException」の Javadoc は次のとおりです。

この例外は、そのような変更が許可されていない場合に、オブジェクトの同時変更を検出したメソッドによってスローされる場合があります。

たとえば、あるスレッドが Collection を変更しているときに、別のスレッドが Collection を反復処理することは一般的に許可されていません。一般に、反復の結果は、これらの状況では未定義です。一部の Iterator 実装 (JRE によって提供されるすべての汎用コレクション実装の実装を含む) は、この動作が検出された場合に、この例外をスローすることを選択する場合があります。これを行う反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗するため、フェイルファスト反復子として知られています。

この例外は、オブジェクトが別のスレッドによって同時に変更されたことを常に示すわけではないことに注意してください。1 つのスレッドが、オブジェクトのコントラクトに違反する一連のメソッド呼び出しを発行すると、オブジェクトはこの例外をスローする可能性があります。たとえば、フェイルファスト反復子を使用してコレクションを反復処理しているときに、スレッドがコレクションを直接変更すると、反復子はこの例外をスローします。

たまたま、それがまさにあなたがやっていることです: "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

を実行すると作成されるインスタンスは1つだけ です。変数はこのインスタンスを参照します。変数も同じインスタンスを参照します。を呼び出すと、パラメータも同じインスタンスを参照します。TreeMapnew TreeMap<Integer, Integer>()stackvisitedOrderdfs(int vertex, TreeMap<Integer, Integer> visited)visitedTreeMap

これで、ループ内でこのTreeMapインスタンスのエントリ セットを反復処理しています。for(Entry<Integer,...反復中にメソッドを呼び出し、dfs(int, TreeMap<Interge, Integer>)このメソッド内でインスタンスに対して a を呼び出し、putそれTreeMapによってインスタンスが変更されます。したがってConcurrentModificationException

あなたが提供したコードから、私の理解では、DFS を実行してgraph配列をに変換しようとしているということです。参照されTreeMapている を反復処理して、を入力しようとしています。発生している例外を解決するには、変数をインスタンスにポイントするだけです。TreeMapstackvisitedOrdervisitedordernew TreeMap<Integer, Integer>()

私が提案した修正は、コードフローとロジックを変更せずに例外を修正することを目的としていることに注意してください.

于 2013-03-06T05:41:17.937 に答える