美文网首页
List三种遍历时对集合进行删除操作的验证

List三种遍历时对集合进行删除操作的验证

作者: SmileMylife | 来源:发表于2019-08-06 21:22 被阅读0次

1.使用for循环遍历集合,并进行删除。

情况一:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
    if (arrayList.get(i) == 3) {
        arrayList.remove(i);
    }
}
结果:[1, 2]

情况二:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
    if (arrayList.get(i) == 1) {
        arrayList.remove(i);
    }
}
结果:[2, 3]

情况三:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
    if (arrayList.get(i) == 2) {
        arrayList.remove(i);
    }
}
结果:[1, 3]

2.使用foreach迭代

情况一:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
    if (Integer.parseInt(i.toString()) == 1) {
        arrayList.remove(i);
    }
}
结果:Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at test.test.IteratorTest.main(IteratorTest.java:21)

情况二:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
    if (Integer.parseInt(i.toString()) == 2) {
        arrayList.remove(i);
    }
}
结果:[1, 3]

情况三:

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
    if (Integer.parseInt(i.toString()) == 3) {
        arrayList.remove(i);
    }
}
结果:Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at test.test.IteratorTest.main(IteratorTest.java:15)

3.使用迭代器进行迭代。

ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
    Integer next = iterator.next();
    if (next == 3) {
        iterator.remove();
    }
}
System.out.println(arrayList.toString());
结果:[1,2]

使用迭代器是正确的选择,但是为什么foreach会报错呢?

源码如下:

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

这是arraylist的一个内部类,而foreach本质上也是使用迭代器进行遍历,但是在每次迭代的时候会去校验集合中元素的个数是否有变更,如果有变更则抛出并发修改异常。

相关文章

  • List三种遍历时对集合进行删除操作的验证

    1.使用for循环遍历集合,并进行删除。 情况一: 情况二: 情况三: 2.使用foreach迭代 情况一: 情况...

  • JAVA集合 - SET

    对集合的操作 对集合主要有三种操作: 插入和删除,以及在指定位置插入和删除 获取元素 对集合进行迭代 不同的集合在...

  • java.util.ConcurrentModification

    平时我们在项目中,对List集合或者map进行迭代并进行增加或者删除操作时,就会出现java.util.Concu...

  • 动态sql-foreach(mybatis)

    一、概要 动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历 foreach可以遍历三种类型,List,a...

  • 并发修改异常java.util.ConcurrentModifi

    1 问题描述 使用foreach或者Iterator遍历list等集合的时候,如果对集合进行了更改,如删除或者增加...

  • 19、mybatis-动态sql-foreach

    一、概要 动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历foreach可以遍历三种类型,List,ar...

  • Mybatis动态SQL之foreach

    一、概要 动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历foreach可以遍历三种类型,List,ar...

  • kotlin精讲-第5章(11)list-下

    list集合变化操作 可以通过slice、subList、drop、dropLast对集合进行变换,产生一个新的集...

  • 对比Vector、ArrayList、LinkedList的区别

    三者都实现了集合框架中的List,也就是所谓的有序集合,都提供按照位置进行定位、添加或者删除操作,都提供迭代器遍历...

  • list集合遍历方式

    Java中List集合的三种遍历方式:①for循环遍历:指定下标长度,使用List集合的size()方法,进行fo...

网友评论

      本文标题:List三种遍历时对集合进行删除操作的验证

      本文链接:https://www.haomeiwen.com/subject/qgdgdctx.html