問題描述
我們都知道,在迭代時從集合中刪除對象的最安全可能也是唯一安全"的方法是首先檢索 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.
這篇關于Iterator 的 remove 方法實際上是如何刪除一個對象的的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!