zoukankan      html  css  js  c++  java
  • ArrayList删除--------ConcurrentModificationException问题

      在做项目中用到List存储数据,在里面做数据操作时候用到了删除。结果抛出ConcurrentModificationException异常。在这里把问题总结一下。

       原因:

    ArrayList进行foreach时所调用的迭代器(内部迭代器Itr)
    /**
    * An optimized version of AbstractList.Itr
    */
    private class Itr implements Iterator<E> {
    int cursor; // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    // expectedModCount是Itr特有的,modCount是公共的
    // expectedModCount和modCount默认是两者相等的;ArrayList进行删除修改都会更新modCount的值
    // 当ArrayList通过foreach进入它的内部迭代器Itr时,expectedModCount就被赋值为modCount的值,后续ArrayList进行增加或删除,只会更新modCount,而不会同步更新expectedModCount
    // 所以迭代器根据这两个值进行判断是否有并发性修改
    int expectedModCount = modCount;
     
    public boolean hasNext() {
    return cursor != size;
    }
    // ArrayList通过foreach(即增强for循环)来循环是调用的是ArrayList中内部类Itr的next()
    @SuppressWarnings("unchecked")
    public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
    throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
    throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
    }
    // ArrayList中迭代器删除方法
    public void remove() {
    if (lastRet < 0)
    throw new IllegalStateException();
    checkForComodification();
     
    try {
    ArrayList.this.remove(lastRet);
    cursor = lastRet;
    lastRet = -1;
    // 通过ArrayList中foreach(即通过ArrayList内部Itr的迭代器)进行删除元素
    // 此时会进行赋值 expectedModCount = modCount;而不会抛出异常
    expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }
    final void checkForComodification() {
    if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
    }
    }
    ArrayList通过foreach迭代是调用的其内部类Itr的next方法。如果通过foreach循环,要去除某些元素,只能通过迭代器删除。因为迭代器删除后会对expectedModCount = modCount设置,不会再循环过程因为expectedModCount 和 modCount值不相等而抛出异常了。如果是通过ArrayList的删除则只会对modCount进行更新,但是ArrayList内部迭代器Itr的属性expectedModCount却没有得到更新,所以抛异常。
     
    解决: List.iterator() 直接用迭代器去迭代,然后去删除元素。
     
  • 相关阅读:
    Docker 网络
    Dockerfile你值得拥有
    Spring boot配置成功后,出现Whitelabel Error Page的解决办法
    ubuntu 创建快捷方式
    Ubuntu Make来安装Visual Studio Code
    ubuntu16.04开机自动挂载Windows分区
    ubuntu下使用罗技Unifying
    酷开电视升级后无法启动
    ArcGIS 10.2安装错误,Error: Internal Error 2753. The File is not marked for installation
    ubuntu16.04下使用wine 运行微信开发小程序
  • 原文地址:https://www.cnblogs.com/technologykai/p/9050796.html
Copyright © 2011-2022 走看看