[英]ConcurrentModificationException when using iterator and iterator.remove()
[英]Why is there no error when using iterator.remove?
如果我使用Iterator.remove()
,一切都很好。 如果使用ArryaList.remove()
,則始終會收到錯誤java.util.ConcurrentModificationException
。
誰能指出原因?
javadocs說了全部:
當不允許對對象進行同時修改時,檢測到該對象的同時修改的方法可能會引發此異常。
例如,通常不允許一個線程修改Collection而另一個線程對其進行迭代。 通常,在這些情況下,迭代的結果是不確定的。 如果檢測到此行為,則某些Iterator實現(包括JRE提供的所有通用集合實現的實現)可能會選擇拋出此異常。 執行此操作的迭代器稱為快速失敗迭代器,因為它們會快速干凈地失敗,而不是在未來的不確定時間內冒任意,不確定的行為的風險。
您正在修改集合並同時對其進行迭代。
基本上是因為這就是它設計的工作方式。 如果從列表中刪除元素,則迭代器將不知道該元素,並且當它嘗試訪問列表中的另一個元素時,列表已更改,並引發錯誤。 但是,如果您通過迭代器刪除元素,則迭代器會知道刪除的內容,對其數據結構進行適當的調整,然后繼續。
所以正是從文檔
當不允許對對象進行同時修改時,檢測到該對象的同時修改的方法可能會引發此異常。
例如,通常不允許一個線程修改Collection而另一個線程對其進行迭代。 通常,在這些情況下,迭代的結果是不確定的。 如果檢測到此行為,則某些Iterator實現(包括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循環在后台使用迭代器。 而且您正在從列表中手動刪除該元素,而不是通過迭代器。 這就是為什么您會得到該例外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.