Java 为什么从arraylist remove方法中删除最后一个元素不符合';t抛出ConcurrentModificationException? listl=newarraylist(); l、 添加(“1”); l、 添加(“2”); l、 添加(“3”); l、 添加(“4”); 迭代器itr=l.Iterator(); while(itr.hasNext()){ 字符串str=itr.next(); 如果(str.equals(“3”)){ l、 移除(str); } }

Java 为什么从arraylist remove方法中删除最后一个元素不符合';t抛出ConcurrentModificationException? listl=newarraylist(); l、 添加(“1”); l、 添加(“2”); l、 添加(“3”); l、 添加(“4”); 迭代器itr=l.Iterator(); while(itr.hasNext()){ 字符串str=itr.next(); 如果(str.equals(“3”)){ l、 移除(str); } },java,Java,为什么上面的代码不抛出ConcurrentModificationException呢?因为元素的删除方式(作为removeIf实现的一部分)是通过迭代器对象完成的 实施: 私有类Itr实现迭代器{ int cursor;//要返回的下一个元素的索引 // ... 公共布尔hasNext(){ 返回光标!=大小; } 其中,cursor是迭代器的实例字段,size是列表的大小 因此,如果在最后的第二个元素上调用remove(),则减小大小,但不更改光标。以前,cursor==size-1;现在

为什么上面的代码不抛出ConcurrentModificationException呢?

因为元素的删除方式(作为removeIf实现的一部分)是通过迭代器对象完成的

实施:

私有类Itr实现迭代器{
int cursor;//要返回的下一个元素的索引
// ...
公共布尔hasNext(){
返回光标!=大小;
}
其中,
cursor
是迭代器的实例字段,
size
是列表的大小

因此,如果在最后的第二个元素上调用
remove()
,则减小
大小
,但不更改
光标
。以前,
cursor==size-1
;现在,
cursor==size

值得注意的是,此
hasNext()
不会调用
checkForComodification()
方法。因此,while循环对
hasNext()
求值,发现它为false,然后停止(您可以通过for each循环观察到相同的行为)


这只是
ArrayList
实现的一个怪癖,而不是您应该依赖的东西。

如果抛出CME,则专门用于从列表中删除元素的方法将完全无用。
@impspect默认实现使用其迭代器遍历集合的所有元素使用Iterator.remove()删除。如果集合的迭代器不支持删除,则将在第一个匹配元素上引发UnsupportedOperationException。
更新的代码:这只是
hasNext()
如何为
ArrayList
实现的人工制品。不要依赖此行为。
List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
l.add("4");
Iterator<String> itr = l.iterator();
while (itr.hasNext()) {
    String str = itr.next();
    if (str.equals("3")) {
        l.remove(str);
    }
}
private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    // ...

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