Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用迭代器';s remove方法实际删除一个对象_Java_Loops_Collections_Iterator - Fatal编程技术网

Java 如何使用迭代器';s remove方法实际删除一个对象

Java 如何使用迭代器';s remove方法实际删除一个对象,java,loops,collections,iterator,Java,Loops,Collections,Iterator,我们都知道,在迭代对象时从集合中移除对象的最安全的“可能也是唯一安全的”方法是,首先检索迭代器,执行循环并在需要时移除 Iterator iter=Collection.iterator(); while(iter.hasNext()){ Object o=iter.next() if(o.equals(what i'm looking for)){ iter.remove(); } } 我想了解的是,不幸的是,我还没有找到一个深入的技术解释,这个删除是

我们都知道,在迭代对象时从集合中移除对象的最安全的“可能也是唯一安全的”方法是,首先检索
迭代器,执行循环并在需要时移除

Iterator iter=Collection.iterator();
while(iter.hasNext()){
    Object o=iter.next()
    if(o.equals(what i'm looking for)){
        iter.remove();
    }
}
我想了解的是,不幸的是,我还没有找到一个深入的技术解释,这个删除是如何执行的,
如果:

将抛出一个
ConcurrentModificationException
,“在技术术语中”迭代器.remove()做什么?它是否删除对象、中断循环并重新启动循环

我在官方文件中看到:

“删除当前元素。如果 尝试调用之前未调用的
remove()
下一步()


“删除当前元素”这一部分让我想到了在“常规”循环=>中发生的完全相同的情况(如果需要,执行相等性测试并删除),但是为什么迭代器循环ConcurrentModification是安全的?

迭代器删除元素的准确程度取决于它的实现,对于不同的集合可能不同。绝对不会打破你的循环。我刚刚了解了ArrayList迭代器是如何实现的,下面是代码:

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();
    }
}
public void remove(){
if(lastRet<0)
抛出新的非法状态异常();
checkForComodification();
试一试{
ArrayList.this.remove(lastRet);
游标=lastRet;
lastRet=-1;
expectedModCount=modCount;
}捕获(IndexOutOfBoundsException ex){
抛出新的ConcurrentModificationException();
}
}

因此,它检查并发修改,使用public ArrayList remove方法删除元素,并增加列表修改的计数器,以便在下一次迭代时不会抛出ConcurrentModificationException。

在对列表进行迭代时无法修改列表的原因是,迭代器必须知道为hasNext()返回什么下一步()

如何做到这一点是特定于实现的,但您可以查看ArrayList/AbstractList/LinkedList等的源代码

还请注意,在某些情况下,您可以使用以下代码作为替代:

List<Foo> copyList = new ArrayList<>(origList);
for (Foo foo : copyList){
  if (condition){
    origList.remove(foo);
  }
}
List copyList=newarraylist(origList);
for(Foo-Foo:copyrist){
如果(条件){
删除(foo);
}
}
但这段代码可能会运行得稍慢一些,因为必须复制集合(仅限于浅拷贝),并且必须搜索要删除的元素

还要注意,如果直接使用迭代器,建议使用for循环而不是while循环,因为这会限制变量的范围:

for (Iterator<Foo> iterator = myCollection.iterator(); iterator.hasNext();){
...
}
for(Iterator Iterator=myCollection.Iterator();Iterator.hasNext();){ ... }
迭代器返回的最后一个元素的索引。它被设置为-1,因为这个元素刚刚从列表中删除。我的Java有点生锈了-但是
ArrayList.this.remove(lastRet)
是什么?为什么需要编写
ArrayList.this
?它是一个内部类还是什么?@BenjaminGruenbaum是的,这一行是从内部类调用的(
private class Itr implements Iterator
),因此
指向
Itr
ArrayList的实例。这
指向
ArrayList
的实例。你可以自己看到:
for (Iterator<Foo> iterator = myCollection.iterator(); iterator.hasNext();){
...
}