为啥java不要在foreach循环里进行元素的remove/add操作

请看文档
public class ConcurrentModificationExceptionextends RuntimeExceptionThis exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
For example, it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.
(请注意这个异常并不是总是在不同线程修改冲突的时候发生。如果一个线程调用了一系列违反了object contract的方法,那么该object也有可能抛出这个异常。举例,如果一个线程在使用一个fail-fast的iterator遍历一个collection的时候直接修改了这个collection,这个iterator就会抛出这个异常)
Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification.(请注意,fail-fast行为不能被保证一定会出现,总得来说,当出现非同步同时修改行为的时候不能给出任何硬性的保证抛出这个异常) Fail-fast operations throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
所谓违反object contract的意思就是 行为未定义,就是这个方法不是设计用来干这个的意思,所以你这个写法什么地方出错都是有可能的。所谓的未定义就是我的这个东西不是这么用的,你这么用可能好使也可能不好使,我不敢说,也不保证。
最后这个异常的抛出也是不保证的,有可能抛有可能不抛,所以才有你观察到的现象。
java里面唯一loop时候删除的安全做法就是用it,也就是你注释掉的那部分。
最后的最后,把一个未定义行为搞得这么神神秘秘,这手册真...

■网友
for循环的本质是利用迭代器进行遍历的~~~~~~

你调用的remove方法用的是List对象的remove~~~~~~
而直接用迭代器的话利用的是迭代器的remove

这个是区别,
你for循环里面调用了给List对象remove就类似于并发操作了~~~~~~

■网友
简答一下:
1、foreach实际上是转换为iterator的hasNext和next方法,大约是下面这样:
public void display2(){ Iterator\u0026lt;String\u0026gt; it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } }


推荐阅读