ArrayList并发修改异常

遇到这么个问题:迭代器并发修改会抛出异常,这个问题之前没有遇到过,特意记录一下:

	public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        //添加元素
        list.add("hello");
        list.add("Java");
        list.add("PHP");
        //获取迭代器
        Iterator<String> it = list.iterator();
        //遍历集合
        while (it.hasNext()) {
            System.out.println(list);
            String s = it.next();
            System.out.println(s);
            if(s.equals("PHP")) {
                list.remove("PHP");
            }
        }
    }
}
/**
 * [hello, Java, PHP]
 * hello
 * [hello, Java, PHP]
 * Java
 * [hello, Java, PHP]
 * PHP
 * [hello, Java]
 * Exception in thread "main" java.util.ConcurrentModificationException
 * 	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
 * 	at java.util.ArrayList$Itr.next(ArrayList.java:851)
 * 	at com.lcg.collection.arryList.iteratorDemo.Test02.main(Test02.java:28)
 */

从结果中可以看到异常是从checkForComodification方法中抛出的,而抛出该异常的条件是modCount 与expectedModCount不相等。从结果中看出虽然报异常了,但是我们想要删除的PHP元素也删除了。所以这个异常是从删除后的下一次集合调用next方法产生的。至于为什么会出现异常也就是modCount 与expectedModCount不相等原因是因为集合的remove方法中会对集合成员变量modCount和size进行修改,调用集合的remove方法后再调用next方法时此时的modCount 与expectedModCount就会不相等所以就会报异常。其实ArrayList集合不仅是remove方法会修改modCount值,其他比如add(),clear()等方法都会修改modCount。

  public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        //添加元素
        list.add("hello");
        list.add("PHP");
        list.add("Java");
        //获取迭代器
        Iterator<String> it = list.iterator();
        //遍历集合
        while (it.hasNext()) {
            String s = it.next();
            if(s.equals("hello")) {
                it.remove();
            }
        }
        System.out.println(list);
        //[PHP, Java]
    }
	

调用迭代器中的remove方法不会有异常的原因是迭代器中的remove方法中对expectedModCount方法进行了重新赋值即expectedModCount = modCount,所以就不会出现expectedModCount与modCount不相等的情况了。

posted @ 2024-06-19 13:56  PostMan_Zc  阅读(21)  评论(0编辑  收藏  举报