foreachサイクルで要素のremove/add操作を行わないでください.remove要素はIterator方式を使用し、同時に操作する場合はIteratorオブジェクトにロックをかける必要があります.

1791 ワード

以下から抜粋:https://www.cnblogs.com/DDiamondd/p/11307825.html
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();
}  
``