zoukankan      html  css  js  c++  java
  • ArrayList remove注意事项

    例子1:

    List<Integer>list=new ArrayList<>();
     list.add(1);
     list.add(2);
     list.add(2);
     list.add(3);
     list.add(4);
     list.add(5);
     for(int i=0;i<list.size();i++){
      if(list.get(i)%2==0){
       list.remove(list.get(i));
      }
    }
    System.out.println(list);

    输出结果:

    [1, 2, 3, 5]

    分析:
    第三个元素没有remove 掉,跟踪:
    第一次循环
    i=0 size=5 当前元素=1 不移除元素
    i=1 size=5 当前元素=2 移除元素
    i=2 size=4 当前元素=3 不移除元素


    在remove 的过程中 size 是移动的,所以 第三个元素给漏掉了

    例子2:

    List<Integer>list=new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    
    System.out.println(list);*/
    
    for (Integer a:list){
     if(a == 2){
      list.remove(a);
     }
    }
    

      

    抛出异常:

    java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at com.student.eureka1.StudentEureka1ApplicationTests.contextLoads(StudentEureka1ApplicationTests.java:31)
    

      

    原因:
    抛出异常代码

    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];
    }
    
    final void checkForComodification() {
    // 是因为 modCount != expectedModCount 不相等
      if (modCount != expectedModCount)
      throw new ConcurrentModificationException();
    }
    

      

    在使用for(Object obj:objList) 这种增强for 循环的时候,每次遍历会进行hasNext 判断,它会创建 List的遍历器Iterator ,在创建的时候它会将 modCount 赋值给 expectedModCount 。并且调用Iterator 的 next 方法。

    在没有调用 list.remove(a); 方法前,expectedModCount 和 modCount是相等的。

    当调用后    注意 list.remove(a); 调用的不是Iterator 的remove 方法,而是 ArrayList的remove 方法, ArrayList的remove 方法 只会更新 modCount 值,不会更新expectedModCount 值,所以不相等报错

    (简单点就是说:你用了Iterator 遍历 但是在里面不是用Iterator  的 remove 方法导致)

    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
    int expectedModCount = modCount;
    
    public boolean hasNext() {
      return cursor != size;
    }
    
    @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];
    }
  • 相关阅读:
    关于微信三点定位法
    PHP 取302跳转后真实 URL 的两种方法
    前端布局神器display:flex
    JS实现document.ready
    为什么无返回值的链表的插入操作头结点一定要用指向指针的指针
    常量字符串和指针
    C语言中指针数组和数组指针的区别
    二维数组简介与使用
    访问者模式
    解释器模式
  • 原文地址:https://www.cnblogs.com/zhangXingSheng/p/10810128.html
Copyright © 2011-2022 走看看