如果我使用Iterator.remove()
,一切都很好。如果我使用ArryaList.remove()
,我總是收到錯誤java.util.ConcurrentModificationException
。爲什麼使用iterator.remove時沒有錯誤?
任何人都可以指出原因嗎?
如果我使用Iterator.remove()
,一切都很好。如果我使用ArryaList.remove()
,我總是收到錯誤java.util.ConcurrentModificationException
。爲什麼使用iterator.remove時沒有錯誤?
任何人都可以指出原因嗎?
基本上,因爲這是它是如何設計的工作。如果從列表中刪除一個元素,迭代器不知道它,當它嘗試訪問列表中的另一個元素時,列表已更改並引發錯誤。但是如果你通過迭代器移除一個元素,那麼itertor知道移除,對其數據結構進行適當的調整,並繼續。
所以從文檔
恰好此異常可能由已檢測到的併發 修改一個對象的當這樣的修改是不允許的方法被拋出。
例如,一個線程在另一個線程遍歷它時通常不允許修改Collection。一般而言,在這些情況下迭代的結果是不確定的。 某些迭代器實現(包括由JRE提供的所有通用 目的集合實現的實現)可能選擇 如果檢測到此行爲則拋出此異常。迭代器做 這就是所謂的快速迭代器,因爲它們很快就會失敗,並且會在未來的未定時間冒着任意的非確定性行爲冒險。
如果只有一個線程在做它,這是不允許的! –
容易的人,我可以添加,如果有多個線程我的錯。 – Sajmon
問題是,如果這樣的誤導性陳述沒有得到糾正,有人可能會閱讀它,並被混淆(充其量)或相信並採取行動。 –
的Javadoc說這一切:
此異常可能由已檢測到的併發 修改一個對象的當這樣的修改是不允許的方法被拋出。
例如,一個線程在另一個線程遍歷它時通常不允許修改Collection。一般而言,在這些情況下迭代的結果是不確定的。 某些迭代器實現(包括由JRE提供的所有通用 目的集合實現的實現)可能選擇 如果檢測到此行爲則拋出此異常。迭代器做 這就是所謂的快速迭代器,因爲它們很快就會失敗,並且會在未來的未定時間冒着任意的非確定性行爲冒險。
您正在修改集合並在同一時間迭代它。
如果您需要在迭代列表時刪除元素,則應始終使用迭代器。
例如
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循環使用引擎蓋下的迭代器。而且您正在手動從列表中刪除元素,而不是通過迭代器。這就是你得到這個例外的原因。
因爲這就是Iterator.remove()的用途? – EJP