探讨java迭代器中为什么不能通过集合的方式删元素而是使用迭代器中的remove()方法经行删除

探讨java迭代器中为什么不能通过集合的方式删元素而是使用迭代器中的remove()方法经行删除

现象
我们在用迭代器来遍历和进行删除元素操作的时候,可能会因为调用集合中的remove()方法,而出现 ConcurrentModificationException异常;
在这里插入图片描述

解决的办法为 :
1. 在迭代器中用迭代器的remove()方法;
2. 在迭代器的遍历外使用集合的删除操作;
3. 使用List类中的ListIterator()方法;(就可以在此迭代器中使用集合的删除方法)
如:
List<String> list=new ArrayList<String>(); ListIterator it=list.ListIterator(); while(it.hasnext()){ if(it.next().equlas("c")) map.remove("c");}...
```
原理:
说起来很简单,原因是因为mian线程和迭代器线程不能同时运行,因为底层加了同步锁;

下面来具体的看看底层实现的原理:

使用调试窗口也可以看到,modCount是 记录了对集合修改的次数expectedModCount是 通过迭代器对集合修改的次数;
在这里插入图片描述

在这里插入图片描述
Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

而这里集合的修改不会影响到迭代器中原来的表的数量,这就造成了
modCount(记录了对集合修改的次数)的值不等于expectedModCount(通过迭代器对集合修改的次数)的值就会抛异常。

再看看java中的API的ConcurrentModificationException描述:

在这里插入图片描述
已经明确的告诉了我们错误的原因是因为线程并发修改的原因,从而抛出了这个错误;

猜你喜欢

转载自blog.csdn.net/weixin_42590083/article/details/112853372