問題描述
我有以下代碼引發(fā) ConcurrentModificationException,因?yàn)槲以谕粋€(gè)列表上使用了兩個(gè)不同的迭代器,其中一個(gè)正在修改列表.所以,第二個(gè)迭代器在讀取列表時(shí)會(huì)拋出異常,因?yàn)槠渌饕呀?jīng)修改了列表.
I have the following code which throws ConcurrentModificationException because I am using two different iterators on the same list and one of them is modifying the list. So, the second iterator throws the exception when reading the list because some other iterator has modified the list.
List<Integer> list = new ArrayList<>();
populate(list);//A method that adds integers to list
ListIterator<Integer> iterator1 = list.listIterator();
ListIterator<Integer> iterator2 = list.listIterator();
while (iterator1.hasNext()) {
if(iterator1.next() < 5)
iterator1.remove();
}
while (iterator2.hasNext()){
if(iterator2.next() < 5) {
//Call handler
}
}
我的問題是 iterator2
如何知道 internally 如果 list
尚未到達(dá)某個(gè)元素,則它已被其他迭代器修改iterator1
還刪除了哪個(gè)?它如何確定其他一些 iterator
已經(jīng)改變了 list
?一種方法是跟蹤大小,但這不是原因,因?yàn)槠渌恍┑骺梢蕴鎿Q任何元素.
My question is how does iterator2
know internally that the list
has has been modified by some other iterator if it has not reached an element which is yet removed by iterator1
? How does it figure out that some other iterator
has mutated the list
? One way could be keep track of size but that can't be the reason since some other iterator can just replace any element.
推薦答案
回答此類問題的一個(gè)好方法是查看源代碼,例如 ArrayList 的源代碼.搜索 ConcurrentModificationException
.
A good way to answer questions like this is to look at the source code, for example the source code for ArrayList. Search for ConcurrentModificationException
.
你應(yīng)該能夠說事情是這樣工作的:
You should be able to tell that things work rather like this:
- 集合對(duì)象有一個(gè)修改計(jì)數(shù),該計(jì)數(shù)從零開始,并在發(fā)生添加或刪除或類似操作時(shí)增加.
- 創(chuàng)建迭代器對(duì)象時(shí),我們將集合的當(dāng)前修改計(jì)數(shù)存儲(chǔ)在迭代器中.
- 每次使用迭代器時(shí),它都會(huì)檢查集合的 mod 計(jì)數(shù)與迭代器在創(chuàng)建時(shí)獲得的 mod 計(jì)數(shù).如果這些值不同,則會(huì)引發(fā)異常.
在您的情況下,列表中 iterator1
執(zhí)行的刪除操作會(huì)更改列表的結(jié)構(gòu)操作計(jì)數(shù) (modCount
).當(dāng) iterator2
被要求刪除時(shí),它會(huì)看到它最初收到的 expectedModCount
為 0,與列表的當(dāng)前 mod 計(jì)數(shù)不同.
In your case, remove operations performed by iterator1
on the list change the structural operation count (modCount
) of the list. When iterator2
is asked to remove, it sees its expectedModCount
, which it received initially as 0, differing from the current mod count of the list.
需要注意的是,it.remove
是一個(gè)特例.當(dāng)?shù)髯约簞h除時(shí),它的 expectedModCount
會(huì)相應(yīng)地調(diào)整,以與底層列表保持同步.
It should be noted that it.remove
is a special case. When an iterator does a remove itself, its expectedModCount
adjusts accordingly, to keep in sync with the underlying list.
這篇關(guān)于Java 中的 Iterator 如何知道何時(shí)拋出 ConcurrentModification 異常的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!