簡體   English   中英

為什么在使用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提供的所有通用集合實現的實現)可能會選擇拋出此異常。 執行此操作的迭代器稱為快速失敗迭代器,因為它們會快速干凈地失敗,而不是在未來的不確定時間內冒任意,不確定的行為的風險。

看一下類ConcurrentModificationException

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

例如

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM