哪位大佬前辈知道为什么用这这种方式遍历删除会报错?

解决方案 »

  1.   

    因为在循环的时候是不允许修改的,必须要使用iterator来操作删除集合中的数据
      

  2.   

    就是list集合是动态的集合,这个动态是指我在删除一个元素的时候那么这个list集合为了保持正确性,集合的长度就要减一,这个元素后边的元素就要向前移动一个位置,就是这个元素后所有元素的下标减一。
      

  3.   

    建议使用普通for(int i= 0; i<size ; i++)更改遍历下标的方式实现动态删除
      

  4.   

    这个时候看源码就好了:public E remove(int index) {
          // 先检查下标索引是是否越界
          rangeCheck(index);
          // ArrayList的修改次数加1
          modCount++;
          // 获取索引对应的元素值
          E oldValue = elementData(index);
          // 获取删除元素后,需要移动的元素的个数
          int numMoved = size - index - 1;
          if (numMoved > 0)
              // 将元素进行移动拷贝
              System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);
          // 最后将多出的位置设置为空,这样说明是没有引用的对象了
          elementData[--size] = null; // Let gc do its work
          // 返回删除的旧值
          return oldValue;
    }
    //ArrayList中Iterator迭代器的实现
    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];
            }        public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                checkForComodification();            try {
                    ArrayList.this.remove(lastRet);
                    cursor = lastRet;
                    lastRet = -1;
                    expectedModCount = modCount;
                } catch (IndexOutOfBoundsException ex) {
                    throw new ConcurrentModificationException();
                }
            }        final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
    }list.remove() 这个操作,导致modCount++这步操作,将ArrayList的修改次数加1。
    在初始化Itr时expectedModCount = modCount = 8 。
    在执行next方法的第一步先进行了checkForComodification方法的检查,因为我们之前进行了remove操作,那么modCount数值减一,实际modCount = 7 。
    modCount 数值和expectedModCount 数值不相等,抛出ConcurrentModificationException异常。
      

  5.   

    没有上面那么复杂   用java自带的集合就可以 import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;public class ListTest {    public static void main(String[] args) {
            List<Integer> list =  new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);
            list.add(5);
    //        for (Integer i : list) {
    //            System.out.println(i);
    //            list.remove(i);
    //        }        List<Integer> list2 = new CopyOnWriteArrayList<>();
            list2.add(1);
            list2.add(2);
            list2.add(3);
            list2.add(4);
            list2.add(5);
            for (Integer i : list2) {
                System.out.println(i);
                list.remove(i);
            }
        }
    }
      

  6.   

            List<Integer> list = new ArrayList<>();
            list.add(3);
            list.add(23);
            list.add(6);
            list.add(8);
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
                list.remove(i);
                i--;
            }        List<Integer> list = new ArrayList<>();
            list.add(3);
            list.add(23);
            list.add(6);
            list.add(8);
            List<Integer> removeList = new ArrayList<>();
            for (Integer integer : list) {
                System.out.println(integer);
                removeList.add(integer);
            }
            list.removeAll(removeList);        List<Integer> list = new ArrayList<>();
            list.add(3);
            list.add(23);
            list.add(6);
            list.add(8);
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
                iterator.remove();
            }常用的几种方式
      

  7.   

    因为这个for循环底层是迭代器,不允许删除,记住就好。还有Arrays.asList()这个返回的内部集合,遍历的时候 改操作也会宝座 像这样的小细节 记住就好,在研究下
      

  8.   

    foreach增强型循环底层使用的迭代器,所以不能直接使用集合的remove方法,这种循环允许遍历不允许增删,要想删除使用迭代器iterator
      

  9.   

    这里的for循环依赖于Iterator的next方法。如果在Iterator循环结束前list的长度变了,next方法就会抛出异常,就像你贴出来的一样。
    你可以直接使用Iterator循环和Iterator.remove方法:
    Iterator<Student> iterator = list.iterator();
    Student student;
            while (iterator.hasNext()) {
                student = iterator.next();
                if (student.getSno().equals(sno))
                    iterator.remove();
            }
      

  10.   

    我写过关于这个的博客可以看一下:https://blog.csdn.net/qq_37141773/article/details/99307038
      

  11.   

    iterator才是线程安全的,而LIST,数组不是
      

  12.   

    用for循环倒叙删除
      

  13.   

    list.removeIf不好用吗。。直接用实现好的就可以的
      

  14.   

    倒叙遍历 完美解决。
    for (int i = list.size()-1; i >=0 ; i--) {}
      

  15.   

    是不是ConcurrentModificationException了?可以参考我这个文章:https://blog.csdn.net/qq_27028561/article/details/103037299
      

  16.   

    原理是fast-fail,即在使用迭代器过程中不允许对集合进行增删改。
      

  17.   

    建议迭代器;
    如果JDK1.8以上的话,可以用removeifimport java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.function.Predicate;/**
     * 
     */
    public class ArrayListDemo {
    public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    list.add(2);
    list.add(6); for (Integer number : list) {
    System.out.println(number);
    } Iterator<Integer> iterator = list.iterator();
    while (iterator.hasNext()) {
    Integer number = iterator.next();
    if (number.equals(4)) {
    try {
    iterator.remove();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    } list.removeIf(new Predicate<Integer>() {
    @Override
    public boolean test(Integer number) {
    return (number.equals(2) || number.equals(4));
    }
    }); for (Integer number : list) {
    System.out.println(number);
    }
    }
    }