美文网首页
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