1

ConcurrentModificationException次のコードでこれが発生するのはなぜですか?

public static ArrayList<ArrayList<String>> buildPath(String s, String e, HashMap<String, ArrayList<String>> visited) {
    ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();
    ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
    ArrayList<String> tmp = new ArrayList<String>();
    tmp.add(e);
    ret.add(tmp);
    boolean needStop = false;
    while (true) {
        for (ArrayList<String> al : ret) { //concurrent exception
            ArrayList<String> pre_words = visited.get(al.get(al.size() - 1));
            for (String pre_word : pre_words) {
                if (pre_word.compareTo(s) == 0) {
                    needStop = true;
                }
                if (needStop && pre_word.compareTo(s) != 0) {
                    continue;
                }
                ArrayList<String> toadd = new ArrayList<String>(al);
                toadd.add(pre_word);
                temp.add(toadd);

            }
        }
        ret = temp;
        if (needStop) {
            for (ArrayList<String> l : ret) {
                Collections.reverse(l);
            }
            return ret;
        }
    }
}

次の変更を行うと、プログラムは正しく実行されます。

から:

for(ArrayList<String> al : ret) {

に:

for(int i =0; i <ret.size() ; i++) {
    ArrayList<String> al = ret.get(i);
4

2 に答える 2

1

イテレータを使用してリストを反復処理しながら、リストに要素を追加しています。これがこの例外の原因です。

非並行コレクションの反復子はフェイルファストです。反復中にコレクションが変更されたことに気付くとすぐに、そのような例外をスローします。

于 2013-08-31T22:59:58.507 に答える
1

while ループを変更するとAConcurrentModificationExceptionが発生しますCollection。これは、この動作がサポートされていないためです。

あなたのループは終わったret

for(ArrayList<String> al : ret)

あなたが変更しますtmp

temp.add(toadd);

次に、後で割り当てtmpますret

ret= temp;

次にループするとき (大きなループwhile(true)) を変更すると、Collectionが得られますConcurrentModificationException

手動でループしたときにそれが得られない理由

for(int i =0; i <ret.size() ; i++)

Iterator拡張 foreach ループで暗黙的に使用される を使用していないためです。を使用しないIteratorと、危険なコードをチェックできません...

于 2013-08-31T23:00:40.743 に答える