Iterator 的 remove 方法实际上是如何删除一个对象的
我们都知道,在迭代时从集合中删除对象的最安全可能也是唯一安全"的方法是首先检索 Iterator
,执行循环并在需要时删除;
We all know that the safest "and probably only safe" way of removing an object from a collection while iterating it, is by first retrieving the Iterator
, perform a loop and remove when needed;
Iterator iter=Collection.iterator();
while(iter.hasNext()){
Object o=iter.next()
if(o.equals(what i'm looking for)){
iter.remove();
}
}
我想了解,但遗憾的是还没有找到深入的技术解释,是如何执行此删除操作,
如果:
What I would like to understand, and unfortunately haven't found a deep technical explanation about, is how this removal is performed,
If:
for(Object o:myCollection().getObjects()){
if(o.equals(what i'm looking for)){
myCollection.remove(o);
}
}
会抛出一个ConcurrentModificationException
,从技术上来说"Iterator.remove()
是做什么的?它会移除对象、中断循环并重新开始循环吗?
Will throw a ConcurrentModificationException
, what does "in technical terms" Iterator.remove()
do? Does it removes the object, breaks the loop and restart the loop?
我在官方文档中看到:
I see in the official documentation:
"删除当前元素.如果有,则抛出 IllegalStateException
尝试调用 remove()
之前没有调用下一个()."
"Removes the current element. Throws
IllegalStateException
if an attempt is made to callremove()
that is not preceded by a call to next( )."
删除当前元素"部分让我想到了常规"循环中发生的完全相同的情况 =>(执行相等测试并在需要时删除),但为什么迭代器循环 ConcurrentModification 安全?
The part "removes the current element", makes me think of the exact same situation happening in a "regular" loop => (perform equality test and remove if needed), but why is the Iterator loop ConcurrentModification-safe?
推荐答案
Iterator 移除元素的具体方式取决于它的实现,对于不同的 Collections 可能会有所不同.绝对不会破坏您所处的循环.我刚刚查看了 ArrayList 迭代器的实现方式,代码如下:
How exactly Iterator removes elements depends on its implementation, which may be different for different Collections. Definitely it doesn't break the loop you're in. I've just looked how ArrayList iterator is implemented and here's the code:
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();
}
}
因此它检查并发修改,使用公共 ArrayList remove 方法删除元素,并增加列表修改的计数器,以便在下一次迭代时不会抛出 ConcurrentModificationException.
So it checks for concurrent modifications, removes element using public ArrayList remove method, and increments counter of list modifications so ConcurrentModificationException won't be thrown at next iteration.
相关文章