1. 程式人生 > 其它 >集合foreach迭代時,邊迭代邊刪除,只能使用迭代器刪除,不能使用集合刪除,否則會導致併發修改異常【for-each和Iterator的選擇】

集合foreach迭代時,邊迭代邊刪除,只能使用迭代器刪除,不能使用集合刪除,否則會導致併發修改異常【for-each和Iterator的選擇】

for-each 邊迭代邊刪除,導致併發修改異常【for-each和Iterator的選擇】

❀ 結論: 當需要邊迭代集合元素,邊刪除指定的元素時,只能使用迭代器,而且是隻能使用迭代器物件的remove方法。

1,看程式碼(報錯程式碼):

2、看程式碼(正確程式碼):

3,解釋一下for-each迭代時需要刪除,為什麼不能選擇集合的方法來刪除,而是選擇迭代器的方法刪除?

1):因為會出現併發修改異常ConcurrentModificationException】----併發(說明至少是兩個執行緒---等下立馬解釋這兩個執行緒如何導致報錯的哈)

2):for-each 底層:就是使用迭代器啦

[ 驗證:通過for-each的例子中生成class檔案使用反編譯工具,反編譯結果出現了java.util.Iterator類,並且出現了其hasNext和next方法。(補充一下:不同反編譯工具出來的結果可能不太一樣,像我使用的工具是:jd-gui-windows-1.6.6,就是沒看到哈哈哈)]

4, 迭代器導致併發修改異常的原因分析:

1):併發修改異常是:兩個執行緒mian執行緒和迭代器執行緒不同步導致的迭代集合時,除了當前的執行緒的執行外,生成了一個迭代器執行緒

2):for-each 迭代元素時是將main執行緒中的元素拷貝到迭代器執行緒。然後main執行緒繼續向下執行[迭代],而迭代器的執行緒也是向下執行,且執行到使用集合來刪除的語句list.remove(Object o)時,main 執行緒中元素刪除,元素數量減少一個,但是迭代器的元素沒有減少【即 Collection 介面存在的刪除指定元素的方法 boolean remove(Object ele),只能刪除集合中的元素,卻不能刪除迭代器中指定的元素。

3)而迭代器內部在每次繼續向下迭代(next方法或remove方法)時,有一個檢查方法checkForComodification

迭代器執行緒每次都會將和當前執行緒(main執行緒)中的元素是否個數相同,若是不同,則報錯:ConcurrentModificationException。

■ 圖是:兩個執行緒mian執行緒和迭代器執行緒