java - 为什么并发修改foreach方法而不是for循环

标签 java concurrentmodification

 ArrayList<Integer> targets = new ArrayList<Integer>();
 targets.add(2);
 targets.add(2);

 for (Integer testInt : targets )
 {
       targets.add(1);
 }

我得到了一个 concurrentModificationException,但是有正常的 for 循环。我没有任何异常(exception)。 在正常的 forloop 中,例如:-

for(int i=0;i<target.size();i++)
{
   System.out.println(target.get(i));
   target.add(22); //no exception
   target.remove(2) // no exception 
}

最佳答案

ForEach 循环不会直接在您的集合上循环。它使用后面的集合的迭代器。您可以在集合实现中看到迭代器。

来自 Arraylist source code

735 
736     public Iterator<E> More ...iterator() {
737         return new Itr();
738     }


An optimized version of AbstractList.Itr
742 
743     private class More ...Itr implements Iterator<E> {
744         int cursor;       // index of next element to return

你的 foreach 循环等于

for(Iterator<Integer> i = targets.iterator(); i.hasNext(); ) {
  Integer element = i.next();
  //To do
}

所以如果你在这里做任何操作,同时你修改集合,引擎盖下的迭代器会混淆并抛出异常。

来自 JLS

List<? extends Integer> l = ...
for (float i : l) ...

将被翻译成:

for (Iterator<Integer> #i = l.iterator(); #i.hasNext(); ) {
    float #i0 = (Integer)#i.next();
    ...

关于java - 为什么并发修改foreach方法而不是for循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45439324/

相关文章:

java - 在 Iterator 中获取 java.util.ConcurrentModificationException

java.util.ConcurrentModificationException 流

java - 可以获取、放置和删除 HashMap 中的元素而无需迭代导致 ConcurrentModificationException?

java - 如何在没有 Gradle 的情况下构建 Android 应用程序

java - 检查字符串是否包含编码字符

java - 谷歌分析图表将应用程序安装到网络应用程序

java - JSP 标记类中的同步块(synchronized block)

java - 为什么会抛出 ConcurrentModificationException 以及如何调试它

java - 如何找到类加载器尝试从哪个 JAR 加载特定类?

java - Java中使用MouseClicked绘制三角形