zoukankan      html  css  js  c++  java
  • 不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁

    不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。 

    正例: Iterator<String> iterator = list.iterator();  

    while (iterator.hasNext()) {              

    String item = iterator.next();                      

     if (删除元素的条件) {                             

     iterator.remove();               

      }     

     } 

    反例: List<String> list = new ArrayList<String>();     

     list.add("1");    

      list.add("2");     

     for (String item : list) {        

      if ("1".equals(item)) {            

      list.remove(item);          

    }      

    }  

    说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的 结果吗? 

    根本原因在于expectedModCount与modCount他们的不相等,由于执行了ArrayList中的remove(),modCount在每一次循环值会发生改变,而expectedModCount并没有发生,在执行checkForComodification()方法就会抛出异常。

    如下代码:


    编译器编译后的代码如下:

    }

    首先大家应该了解,对集合做remove,and等操作会触修改次数(modCount)的增加。


    以下是集合实现的Iterator.hasNext()方法


    cursor:下一个元素的索引位置(调用Interator.next()是会触发cursor+1)

    size:集合长度

    总结:如果我们我们用foreach删除的元素刚好是最后一个,删除完成前cursor刚好等于size的大小。但是,删除完成后size的数量减1,但是cursor并没有变化。导致下一次循环不相等继续向下执行,导致检查数组不通过,抛出java.util.ConcurrentModificationException

    为什么使用下面的方法就不会出现这种情况:


    请看箭头所指处:

    foreach是直接调用集合的删除方法,而上面是调用iterator的删除方法:


    相信大家一看便知!

    1.首先检查集合

    2.删除元素

    3.cursor重新赋值

    4.检查集合参数重新赋值


    ---------------------
    作者:这个人好帅
    来源:CSDN
    原文:https://blog.csdn.net/weixin_39032575/article/details/80724984
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    redis分布式锁解决超卖问题
    redis使用
    Xcode 解决日志打印不全问题
    苹果电脑系统怎么重装?这几步就可以轻松搞定
    Mac 一键显示所有隐藏文件 不要那么六好吧
    iOS导入高德地图出现缺失armv7--"Undefined symbols for architecture armv7"
    如何生成.a文件,小心有坑!!
    保护你的代码,生成.a文件以及.framework文件需要注意的地方
    二维码扫描工具实现
    iOS 调整图片尺寸,告诉你的UI,别问我尺寸!我要最大的
  • 原文地址:https://www.cnblogs.com/jimcsharp/p/10168789.html
Copyright © 2011-2022 走看看