ArrayList<String> al = new ArrayList<String>();
al.add("a");
al.add("b");
al.add("b");
al.add("c");
al.add("d");

Iterator<String> iter = al.iterator();
while (iter.hasNext()) {
    if (iter.next().equals("a")) {
        iter.remove();
    }
}

同样的,也会报出ConcurrentModificationException。

最踏实的章程,使用下标的措施:

ArrayList是最常用的意气风发种java会集,在付出中大家经常要求从ArrayList中删除特定成分。有两种常用的主意:

ArrayList<String> al = new ArrayList<String>();
    al.add("a");
    al.add("b");
    //al.add("b");
    //al.add("c");
    //al.add("d");

    for (int i = 0; i < al.size(); i++) {
        if (al.get(i) == "b") {
            al.remove(i);
            i--;
        }
    }
ArrayList<String> al = new ArrayList<String>();
    al.add("a");
    al.add("b");
    al.add("b");
    al.add("c");
    al.add("d");

    for (String s : al) {
        if (s.equals("a")) {
            al.remove(s);
        }
    }

查看迭代器本人的删减方法,果然如此,每一回删除之后都会改善expectedModCount为modCount。那样的话就不会抛出特别

modCount是会晤改良的次数,当remove成分的时候就会加1,领头值为集聚的大大小小。迭代器每一回得到下三个要素的时候,都会进展推断,比较会集订正的次数和希望改革的次数是还是不是风度翩翩致,假诺不意气风发致,则抛出极其。查看集结的remove方法:

在代码中,删除成分后,供给把下标减风流倜傥。那是因为在每一回删除元素后,ArrayList会将尾巴部分的成分依次往上挪多个职位(正是copy),所以,下一个索要拜见的下标照旧当下下标,所以必得得减风姿浪漫才干把富有因素都遍历完

能够观察,删除成分时modCount已经加意气风发,但是expectModCount并不曾增添。所以在行使迭代器遍历下三个因素的时候,会抛出十二分。那怎么消除那些难点吗?其实采用迭代器本人的删除方法就从没有过难点了

再有其余风华正茂种艺术:

final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
}
List<String> list = new ArrayList<String>();
// Insert some sample values.
list.add("Value1");
list.add("Value2");
list.add("Value3");

// Get two iterators.

Iterator<String> ite = list.iterator();

Iterator<String> ite2 = list.iterator();
 // Point to the first object of the list and then, remove it.

ite.next();

ite.remove();
/* The second iterator tries to remove the first object as well. The object does not exist and thus, a ConcurrentModificationException is thrown. */

ite2.next();

ite2.remove();
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
        at java.util.ArrayList$Itr.next(ArrayList.java:836)
        at com.mine.collection.TestArrayList.main(TestArrayList.java:17)

新澳门31999Java ArrayList删除特定元素的方法。从那多少个货仓能够见到,是ArrayList的迭代器报出的极其,表达经过成分遍历集适那时候,实际上是运用迭代器举行访谈的。可怎会时有产生这几个极其呢?打断点单步调节和测量检验进去开掘,是那行代码抛出的老大:

private void fastRemove(int index) {
    modCount++;
    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
}

这里使用要素遍历的方法,当拿到到的这段时间因素与一定元素相符有的时候候,即除去成分。从表面上看,代码没至极,然则运维时却报这么些:

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();
        }
}

实际上从这几个的项目应该是能体会掌握原因:ConcurrentModificationException.同不常候校订拾贰分。看下边叁个例子

建议之后操作集结类的元素时,尽量接受迭代器。不过还大概有三个地点不知晓,modCount和expectedModCount那五个变量毕竟是为什么用的?为何集结在拓宽操作时须求纠正它?为何迭代器在收获下二个成分的时候须求判别它们是不是相仿?它们存在总是有道理的吧

发表评论

电子邮件地址不会被公开。 必填项已用*标注