2012-06-11 26 views
-1

如果我使用Iterator.remove(),一切都很好。如果我使用ArryaList.remove(),我總是收到錯誤java.util.ConcurrentModificationException爲什麼使用iterator.remove時沒有錯誤?

任何人都可以指出原因嗎?

+1

因爲這就是Iterator.remove()的用途? – EJP

回答

2

基本上,因爲這是它是如何設計的工作。如果從列表中刪除一個元素,迭代器不知道它,當它嘗試訪問列表中的另一個元素時,列表已更改並引發錯誤。但是如果你通過迭代器移除一個元素,那麼itertor知道移除,對其數據結構進行適當的調整,並繼續。

1

所以從文檔

恰好此異常可能由已檢測到的併發 修改一個對象的當這樣的修改是不允許的方法被拋出。

例如,一個線程在另一個線程遍歷它時通常不允許修改Collection。一般而言,在這些情況下迭代的結果是不確定的。 某些迭代器實現(包括由JRE提供的所有通用 目的集合實現的實現)可能選擇 如果檢測到此行爲則拋出此異常。迭代器做 這就是所謂的快速迭代器,因爲它們很快就會失敗,並且會在未來的未定時間冒着任意的非確定性行爲冒險。

已經看清楚Class ConcurrentModificationException

+0

如果只有一個線程在做它,這是不允許的! –

+0

容易的人,我可以添加,如果有多個線程我的錯。 – Sajmon

+0

問題是,如果這樣的誤導性陳述沒有得到糾正,有人可能會閱讀它,並被混淆(充其量)或相信並採取行動。 –

4

的Javadoc說這一切:

此異常可能由已檢測到的併發 修改一個對象的當這樣的修改是不允許的方法被拋出。

例如,一個線程在另一個線程遍歷它時通常不允許修改Collection。一般而言,在這些情況下迭代的結果是不確定的。 某些迭代器實現(包括由JRE提供的所有通用 目的集合實現的實現)可能選擇 如果檢測到此行爲則拋出此異常。迭代器做 這就是所謂的快速迭代器,因爲它們很快就會失敗,並且會在未來的未定時間冒着任意的非確定性行爲冒險。

您正在修改集合並在同一時間迭代它。

0

如果您需要在迭代列表時刪除元素,則應始終使用迭代器。

例如

List<String> list = //... 
//... 
Iterator<String> iter = list.iterator(); 

while(iter.hasNext()) { 
    String str = itr.next(); 
    //... 
    if(/* ... */) { 
     iter.remove(str); 
    } 
} 

這是從列表中刪除元素的最安全方法,當您遍歷列表時。

注意:你不應該做的事情如下:

List<String> list = //... 
//... 
for(String str : list) { 
    if(/* ... */) { 
     list.remove(); // <-- should not do this 
    } 
} 

主要在哪裏,你會在ConcurrentModificationException結束。增強的for循環使用引擎蓋下的迭代器。而且您正在手動從列表中刪除元素,而不是通過迭代器。這就是你得到這個例外的原因。

相關問題