foreachサイクルで要素のremove/add操作を行わないでください.remove要素はIterator方式を使用し、同時に操作する場合はIteratorオブジェクトにロックをかける必要があります.
1791 ワード
以下から抜粋:https://www.cnblogs.com/DDiamondd/p/11307825.html
11.【強制】foreachサイクルで要素のremove/add操作を行わないでください.remove要素はIterator方式を使用し、同時に操作する場合はIteratorオブジェクトにロックをかける必要があります.正例:
反例:
説明:以上のコードの実行結果は予想外になるに違いありませんが、「1」を「2」に変えてみると、同じ結果になりますか?
なぜ上記の例は特殊なのか、リストセットには2つのデータしかないため、最初のデータのみを削除する場合はlistを実行する.remove(temp)後、cursor=size-1、size=size-1となるため、ループが押し出されます.異常は投げ出されなかった.
例を次のように変更します.
3つの要素があります.最後から2番目の要素を直接削除しても異常は出ません(cursor=size-1、size=size-1の場合、ループを終了するため)、他の要素を直接削除してもConcurrentModificationException異常が出ます!!
次のような書き方であれば、さらに異常を投げ出します!
iteratorのremove/addメソッドを直接使用してコレクションを変更します.
11.【強制】foreachサイクルで要素のremove/add操作を行わないでください.remove要素はIterator方式を使用し、同時に操作する場合はIteratorオブジェクトにロックをかける必要があります.正例:
List list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ( ) {
iterator.remove();
}
}
反例:
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}
説明:以上のコードの実行結果は予想外になるに違いありませんが、「1」を「2」に変えてみると、同じ結果になりますか?
なぜ上記の例は特殊なのか、リストセットには2つのデータしかないため、最初のデータのみを削除する場合はlistを実行する.remove(temp)後、cursor=size-1、size=size-1となるため、ループが押し出されます.異常は投げ出されなかった.
例を次のように変更します.
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
for (String temp : list) {
if("1".equals(temp)){
list.remove(temp);
}
}
3つの要素があります.最後から2番目の要素を直接削除しても異常は出ません(cursor=size-1、size=size-1の場合、ループを終了するため)、他の要素を直接削除してもConcurrentModificationException異常が出ます!!
次のような書き方であれば、さらに異常を投げ出します!
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
for (String temp : list) {
list.remove(temp);
}
iteratorのremove/addメソッドを直接使用してコレクションを変更します.
List list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
String temp = (String) iterator.next();
iterator.remove();
}
``