不要在 foreach 循環(huán)里進行元素的 remove/add 操作。remove 元素請使用 Iterator 方式,如果并發(fā)操作,需要對 Iterator 對象加鎖

不要在 foreach 循環(huán)里進行元素的 remove/add 操作。remove 元素請使用 Iterator 方式,如果并發(fā)操作,需要對 Iterator 對象加鎖。

正例: Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (刪除元素的條件) {

iterator.remove();

}

}

反例: List<String> list = new ArrayList<String>();

list.add("1");

list.add("2");

for (String item : list) {

if ("1".equals(item)) {

list.remove(item);

}

}

說明:以上代碼的執(zhí)行結(jié)果肯定會出乎大家的意料,那么試一下把“1”換成“2”,會是同樣的 結(jié)果嗎?

根本原因在于expectedModCount與modCount他們的不相等,由于執(zhí)行了ArrayList中的remove(),modCount在每一次循環(huán)值會發(fā)生改變,而expectedModCount并沒有發(fā)生,在執(zhí)行checkForComodification()方法就會拋出異常。

如下代碼:

編譯器編譯后的代碼如下:

}

首先大家應(yīng)該了解,對集合做remove,and等操作會觸修改次數(shù)(modCount)的增加。

以下是集合實現(xiàn)的Iterator.hasNext()方法

cursor:下一個元素的索引位置(調(diào)用Interator.next()是會觸發(fā)cursor+1)

size:集合長度

總結(jié):如果我們我們用foreach刪除的元素剛好是最后一個,刪除完成前cursor剛好等于size的大小。但是,刪除完成后size的數(shù)量減1,但是cursor并沒有變化。導致下一次循環(huán)不相等繼續(xù)向下執(zhí)行,導致檢查數(shù)組不通過,拋出java.util.ConcurrentModificationException

為什么使用下面的方法就不會出現(xiàn)這種情況:

請看箭頭所指處:

foreach是直接調(diào)用集合的刪除方法,而上面是調(diào)用iterator的刪除方法:

相信大家一看便知!

1.首先檢查集合

2.刪除元素

3.cursor重新賦值

4.檢查集合參數(shù)重新賦值

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容