Java-使用经典循环时会同时进行修改异常



是否有机会在使用经典循环时发生并发修改异常?

import java.util.*;
class IterTest{
    public static void main(String[] args){
        List<Integer> nums = new ArrayList<>();
        nums.add(18);
        nums.add(1);
        nums.add(14);
        nums.add(13);
        System.out.println("Nums ->"+nums);
        int len = nums.size();
        for(int index=0;index < len ;index++){          
            System.out.println(" Current >>"+nums.get(index));
            System.out.println(" Removing >>"+nums.remove(index));          
        }
    }
}

不,没有机会。使用迭代器时可能会发生同时修改异常,请查看Java中的故障安全和失败的迭代器

否,此代码不会给出ConcurrentModificationException。当收藏的视图被从其下方更改而来时,通常会发生这种例外。当Iterator迭代(在增强的语句中隐含使用)或获得subList(),修改基础列表,然后继续使用Sublist。

但是,此代码将遇到与"破坏"循环的相同条件,除非会抛出不同的例外。循环范围基于列表的初始大小。但是,循环主体从列表中删除元素,因此代码最终将在列表的边界之外索引,从而导致IndexOutOfBoundsException

如何修复此代码取决于您要做什么。最初,使用列表索引而不是Iterator,避免使用ConcurrentModificationException似乎很明智。但是,如果列表在循环过程中进行了结构修改(即添加或删除元素),则需要仔细调整索引和环界,否则可能会跳过元素,重复或IndexOutOfBoundsException

否,正如其他答案所建议的那样,ConcurrentModificationException不会在给定代码中发生。

那么何时发生contrentModificationException?

在单线环境中,通常会在您使用迭代器循环收集并同时修改它时发生。

为什么?

如果您检查迭代器实现的源代码,则每当您使用任何迭代器(例如Next Next(),remove())时,它总是会进行checkForcomodification()。例如,arraylist.java中该方法的代码是:

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

其中 modCount 是在ArrayList类级别维护的静态变量,该变量表示该列表已在结构上修改的次数。预期的修改计数预期modcount 保持在迭代器类级别,最初等于modCount。

因此,只要预期的修改数与实际完成的修改不匹配,您就会得到异常。

在您的情况下,您尚未使用任何此事,因此不会进行共同修改的检查,因此您将无法获得ConcurrentModificationException

注意:如本答案所述,您将获得IndexOutOfBoundsException,因为您已经在循环中检查了index < len,并且len初始化为数组的初始大小。一个简单的解决方案是:

 for(int index=0;index < nums.size;index++)

相关内容

  • 没有找到相关文章

最新更新