概述
深入理解ArrayList iterator remove
- 具体是为什么呢?
- 看下底层方法
- 最后附上正确的remove方法
我们都知道在list遍历中使用ArrayList.remove 是不安全的。会直接抛出运行时异常java.util.ConcurrentModificationException
具体是为什么呢?
通俗的来讲是因为list列表里面发生了index偏差,当你remove了一个元素,会影响整个list的长度,并且在获取下一元素的时候发生错误。
所以我们要用iterator.next获取下个节点
看下底层方法
我们定位到ArrayList.class中(ArrayList继承List,List继承Collection)
在List.class中,我们可以看到iterator()、get()、add()等抽象方法,并在ArrayList中,对这些抽象方法进行重写。
在ArrayList中有两个关键的参数modCount、expectedModCount,我称为运算计数,可以保证数据准确性
每次调用add,remove,clear,modCount都会自增+1,expectedModCount则为期待的运算计数。
当我们用遍历列表,foreach、iterator都会更新赋值 modCount =expectedModCount。
Itr() {
this.expectedModCount = ArrayList.this.modCount;
}
如果遍历list列表的期间,用了list.remove(),modCount++会自增,然鹅expectedModCount却没有更新。
if (this.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
抛出异常ConcurrentModificationException。
//iterator的remove
public void remove() {
if (this.lastRet < 0) {
throw new IllegalStateException();
} else {
this.checkForComodification();
try {
ArrayList.this.remove(this.lastRet);
this.cursor = this.lastRet;
this.lastRet = -1;
this.expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException var2) {
throw new ConcurrentModificationException();
}
}
}
//普通的remove
private void fastRemove(Object[] es, int i) {
++this.modCount;
int newSize;
if ((newSize = this.size - 1) > i) {
System.arraycopy(es, i + 1, es, i, newSize - i);
}
es[this.size = newSize] = null;
}
但是如果用Iterator的remove里面,不仅会自增自己的modCount,还会更新expectedModCount,
校验数据正确性时expectedModCount = modCount ,保证了数据的正确性
最后附上正确的remove方法
List<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
arrayList.add(Integer.valueOf(i));
}
// 复现方法一
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
Integer integer = iterator.next();
if (integer.intValue() == 5) {
//arrayList.remove(integer);
iterator.remove();
}
}
System.out.println(arrayList.toString());
最后
以上就是火星上自行车为你收集整理的深入理解ArrayList iterator remove的全部内容,希望文章能够帮你解决深入理解ArrayList iterator remove所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复