我是靠谱客的博主 火星上自行车,最近开发中收集的这篇文章主要介绍深入理解ArrayList iterator remove,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

深入理解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所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部