我是靠谱客的博主 拼搏薯片,最近开发中收集的这篇文章主要介绍集合在迭代的时候为什么不能调用集合的remove(),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在这里插入图片描述

为什么集合在迭代的时候,不能调用集合的remove()方法呢?下面我们来探究一下

集合遍历不能调用集合的移除方法,包括map集合和list还有set集合等等。会造成什么情况和原因,本文的最后会有详细解释。
你在集合中进行迭代的时候,你调用集合的remove()方法删除元素的时候,会抛出以下异常

在这里插入图片描述

modCount属性是ArrayList的属性,当你调用集合的remove()一次,它就会+1,而迭代器中也有一个exceptedModCount,

你每次创建一个迭代器的时候,就会将集合中的modCount属性的值赋给迭代器中的expectedModCount属性,让他们开始相等。

这是集合的remove()方法


public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
你每次调用集合的remove()都会让modCount++,表示你调用集合的remove()调用了几次
ArrayList list=new ArrayList();
Iterator it=list.iterator();
while(it.hasNext()){
it.next();

}

你每次调用it.next(),他都会调用检查expectedModCount是否和modCount相等,不相等说明你在迭代的时候调用了集合的remove()方法。这时候执行执行next()方法时就会抛出并发异常。大家可能会疑惑为什么会这样呢,慢慢往下看。

这是ArrayList获取迭代器的方法在这里插入图片描述
这是我们获取迭代器中的熟识的方法在这里插入图片描述
下面是迭代器的remove()方法
在这里插入图片描述
上面的lastRet会在你调用next()时将lastRet设置为当前指针的位置的下标,这样你在调用迭代器的remove()方法时,就可以将此元素移除,然后将后面的元素往前移,在将lastRet设置为-1,防止你再次移除。

  • 迭代器remove进行两次检查
    1. 你每次调用迭代器的remove(),开头都会进行lastRet检查,判断你是否第一次调用迭代器,因为你每次调用都会将lastRet设为-1,所以一次循环只能调用一次.
    2. 而checkForCoCodification()会进行判断exceptedModCount和modCount是否相等,这是为了防止你在迭代时调用集合的remove().
    3. 然后里面调用集合的remove()删除当前遍历的最后一个,这是集合的modCount+1,所以进行赋值exceptedModCount=modCount。意义就是不让你遍历时自己调用集合的remove任意删除造成数据读取不到(你每次删除就会让数组从删除后面每个元素往前移一次,但记录当前遍历位置的指针不动,有可能会造成少读。

造成少读的原因:
1,比如cursor指针指向数组的第四个元素,但还没有读,但你将当前指针前面的删除了,从删除位置起的所有元素都会往前移一个,这时就造成你原来指针指向的还没读的元素往前移了,你再用迭代器获取就获取不到了。
2,如果你删除的是记录当前指针位置后面的元素不会有影响,因为删除后面的,后面的元素往前移,但你指针当前的元素没有移动,所以就不会少读,所以说你只要删除的是指针后面的元素就不会有影响,但为了保证万无一失,源码编写者就不允许你遍历时便便删除,而是他给你提供迭代器的删除方法,有规律的删除,他在有规律的移动;他的方案就是:可以删除你当前遍历的元素,再将指针向前移动一位,并且只循序你调用一次迭代器的remove(),这样就解决了你遍历时自己调用集合remove任意删除造成少读的情况).

如果你还是没有太懂顺着我的思路去看看源码,这样你亲身体验一下可能就会更加明白了,其实很多问题都可以在源码中找到答案,你可以慢慢地锻炼这种能力,时间长了,你的能力就会得到潜移默化的影响。有什么意见大家可以提出来,谢谢大家;

最后

以上就是拼搏薯片为你收集整理的集合在迭代的时候为什么不能调用集合的remove()的全部内容,希望文章能够帮你解决集合在迭代的时候为什么不能调用集合的remove()所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部