美文网首页
List 使用迭代器遍历时,为什么不能调用List.remove

List 使用迭代器遍历时,为什么不能调用List.remove

作者: 填坑之路_DK | 来源:发表于2021-01-26 18:14 被阅读0次

    java提供的所有List 均直接或间接继承 AbstractList ,先看AbstractList 类的定义

    //代码可能有所删减或修改,但代码含义不变
    public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>{ 
        
        protected transient int modCount = 0;  //集合被修改的次数(add 和 remove 时会++)
        
         private class Itr implements Iterator<E> { //内部类,迭代器实现 实际上还是在根据下标获取数据
            int cursor = 0;  //下一个元素的下标
            int lastRet = -1;  //最后一次返回元素的下标,如果被删除 重置为-1
            int expectedModCount = modCount; //期望集合被修改的次数  默认等于当前集合被修改的次数
             
            public E next() {
                if (modCount != expectedModCount)  //使用迭代器遍历时不能删除元素!!!!!!!!!!!!!!!!!!!
                    throw new ConcurrentModificationException();
                    int i = cursor;
                    E next = get(i);
                    lastRet = i;
                    cursor = i + 1;
                    return next;
            }
             
           public void remove() {
                if (lastRet < 0)
                    throw new IllegalStateException();
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                    AbstractList.this.remove(lastRet);
                    if (lastRet < cursor)
                        cursor--;
                        lastRet = -1;
                    expectedModCount = modCount; //可以使用迭代器对象删除!!!!!!!!!!!
            }   
         }
    }
    

    具体说明

    1. 提供 modCount 成员变量 记录集合实际被修改次数
    2. 默认的迭代器 Itr 实现了 禁止在迭代器循环中 直接使用集合删除元素,通过比较 \color{#FF0000}{期望集合被修改的次数}\color{#FF0000}{当前集合被修改的次数}
    3. 原则上不推荐在循环时删除元素,如果一定需要删除,可以使用 迭代器 Itr.remove();进行删除

    相关文章

      网友评论

          本文标题:List 使用迭代器遍历时,为什么不能调用List.remove

          本文链接:https://www.haomeiwen.com/subject/kqqnzktx.html