當我們在當前節點之後添加某個對象或在當前節點之後刪除某個對象時,Iterator
如何拋出ConcurrentModificationException
。 Iterator
是否保留對底層集合的副本或引用?如何在迭代時拋出ConcurrentModificationException
回答
迭代器維護對基礎集合的引用。如果添加或刪除元素,則迭代器可能會留在不可能的索引處,或者集合可能會更改迭代器的「下方」。
因此,當您嘗試在迭代過程中修改集合時,大多數集合不會讓迭代器受到損壞,而是在您嘗試在迭代時修改集合時引發ConcurrentModificationException,因此您不會發現具有不可預知的損壞的迭代器。
當然,迭代器有一個鏈接到底層集合,這避免了副本。如果您在ArrayList迭代器(ListItr)的源代碼中尋找示例,則會看到它主要包含指向列表和遊標的鏈接。
所以,不要在線程之間共享迭代器,也不要修改迭代的集合。
通過契約,您不能在迭代時修改集合(除了使用Iterator.remove()
等)。
當您這樣做時,該集合不會隨機失敗,而是可以跟蹤修改的次數,並在檢測到併發修改時拋出ConcurrentModificationException
。
ConcurrentModificationException可能是你的朋友,你應該學會忍受它。但是,爲了完整性:
那裏有非Oracle集合,不會拋出ConcurrentModificationException。他們更快(因爲他們不花時間檢查),顯然,更靈活,但使用時需要更加小心。
Oracle有四個(最後一個計數)「併發」類,它們不會在java.util.concurrent(ConcurrentHashMap,ConcurrentLinkedQueue,ConcurrentSkipListMap和ConcurrentSkipListSet)中拋出它。它們比非並行等價物稍微慢一些,但它們是線程安全的和它們不要阻止。他們不會加擾你的數據,無論你做什麼什麼,但他們不會停止你從擾亂它。
,拆卸,您可以使用iterator.remove(),如下所示:
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Object object = iterator.next();
/* ... */
if (condition) {
iterator.remove();
}
對於添加你可以取代的ListIterator簡單的迭代器,如下
ListIterator<Object> iterator = list.listIterator();
iterator.add(new Object());
- 1. ArrayList迭代器拋出ConcurrentModificationException
- 2. 兩個迭代器拋出ConcurrentModificationException
- 3. 如果我在迭代結束時在ArrayList中添加元素,則拋出ConcurrentModificationException
- 4. ConcurrentModificationException使用迭代器時
- 5. ConcurrentModificationException拋出iterator.remove
- 6. 爲什麼沒有故障安全迭代器拋出ConcurrentModificationException?
- 7. 關於的LinkedBlockingQueue迭代器不會拋出ConcurrentModificationException
- 8. HashMap迭代器ConcurrentModificationException
- 9. 如何跟蹤哪個HashMap拋出ConcurrentModificationException
- 10. ConcurrentModificationException嘗試迭代列表時
- 11. ConcurrentModificationException當通過連接迭代時
- 12. 迭代器,但仍ConcurrentModificationException的
- 13. ConcurrentModificationException的迭代地圖
- 14. 爲什麼不拋出ConcurrentModificationException
- 15. 更新mongo拋出ConcurrentModificationException?
- 16. 可以Collection.size()拋出ConcurrentModificationException?
- 17. HashMap中拋出ConcurrentModificationException的
- 18. 如何迭代一個HashMap,同時避免ConcurrentModificationException
- 19. 如何解決使用foreach迭代List時的ConcurrentModificationException?
- 20. 迭代器拋出KeyNotFoundException
- 21. ConcurrentModificationException當我在ArrayList上迭代
- 22. 爲什麼在迭代器上調用remove()會給出ConcurrentModificationException?
- 23. WMEncoder在一次迭代後拋出OutOfMemoryException
- 24. ConcurrentModificationException迭代通過Arraylist(不刪除)
- 25. 避免迭代器的方法ConcurrentModificationException
- 26. 一個奇怪的ConcurrentModificationException迭代
- 27. ConcurrentModificationException的當迭代通過列表
- 28. HashMap上的ConcurrentModificationException(不會迭代它)
- 29. ConcurrentModificationException的使用迭代循環
- 30. 什麼時候ArrayList.Itr#next()在這一行上拋出ConcurrentModificationException?
迭代器不會有加方法,接下來只有3個方法,hasnext,remove。 – banjara
您應該使用ListIterator而不僅僅是Iterator類型 – Moesio