10

巡回セールスマン プログラムを書いているときに、これに遭遇しました。内側のループについては、

for(Point x:ArrayList<Point>) {
// modify the iterator
}

しかし、そのリストに別のポイントを追加すると、ConcurrentModicationExceptionスローされました。

ただし、ループを次のように変更すると、

for(int x=0; x<ArrayList<Point>.size(); x++) {
// modify the array
}

ループは例外をスローすることなく正常に実行されました。

両方とも for ループなので、一方が例外をスローするのに、もう一方が例外をスローしないのはなぜですか?

4

5 に答える 5

10

他の人が説明したように、イテレータは基になるコレクションへの変更を検出します。これは、予期しない動作を引き起こす可能性があるため、良いことです。

コレクションを変更するこのイテレータのないコードを想像してみてください。

for (int x = 0; list.size(); x++)
{
  obj = list.get(x);
  if (obj.isExpired())
  {
    list.remove(obj);
    // Oops! list.get(x) now points to some other object so if I 
    // increase x again before checking that object I will have 
    // skipped one item in the list
  }
}
于 2010-03-07T18:29:14.330 に答える
6

最初の例ではイテレータを使用していますが、2番目の例では使用していません。同時変更をチェックするのはイテレータです。

于 2010-03-07T18:19:38.850 に答える
2

最初のコードはイテレータを使用しているため、コレクションの変更は許可されていません。x.get(i)を使用して各オブジェクトにアクセスしている2番目のコードは、イテレータを使用しないため、変更が許可されます。

于 2010-03-07T18:20:18.180 に答える
0

コードを実行して観察すると、ループの最初の反復は正常に機能するが、2 番目の反復でスローされることがわかります。ConcurrentModicationException

if はnext()、要素の数が変更されていないかどうかをメソッドがチェックするためです。

わかりやすい説明については、http://javaadami.blogspot.com/2007/09/enhanced-for-loop-and.htmlを参照してください。

于 2014-04-26T21:28:23.367 に答える
0

List最初の例で行っているように、反復処理中にa を変更することはできません。2番目は、単純に通常のforループです。

于 2010-03-07T18:28:03.133 に答える