摘要:單線程的迭代過程中刪除集合元素以上代碼會(huì)出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時(shí)調(diào)用了這個(gè)是調(diào)用返回的對(duì)象這個(gè)對(duì)象的方法如下圖方法首先它會(huì)調(diào)用這個(gè)方法這個(gè)方法很簡單就是比較這兩個(gè)值是不是相等不相等就拋出異常如下圖這兩個(gè)值為什么會(huì)不相
單線程的Iterator迭代過程中刪除集合元素
public class TestIterator { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); list.add("6"); Iterator it = list.iterator(); while (it.hasNext()) { String next = it.next(); if("3".equals(next)) { list.remove(3); } System.out.println(next); } } }
以上代碼會(huì)出現(xiàn)如下異常
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at caoyan.test.TestIterator.main(TestIterator.java:22)
從后往前看:
TestIterator第22行代碼:
String next = it.next();
我們在執(zhí)行代碼22行時(shí)調(diào)用了it.next();這個(gè)it是ArrayList調(diào)用iterator()返回的對(duì)象;這個(gè)對(duì)象的next()方法如下圖:
public E next() { checkForComodification(); ...
next()方法首先它會(huì)調(diào)用checkForComodification()這個(gè)方法,這個(gè)方法很簡單,就是比較expectedModCount , modCount 這兩個(gè)值是不是相等;不相等就拋出異常;如下圖:
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
這兩個(gè)值為什么會(huì)不相等,它們各自代表什么含義呢,我們看ArrayList的iterator()方法:
public Iteratoriterator() { return new Itr(); } /** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;
Arraylist的iterator()方法,直接創(chuàng)建了一個(gè)私有的內(nèi)部類Itr的對(duì)象;expectedModCount 就是定義在這個(gè)Itr中的成員變量,而且,在初始化的時(shí)候,將modCount賦值給expectedModCount,說明在剛生成Iterator的時(shí)候這兩個(gè)值是相等的.modCount是定義在哪里呢,看下面源碼
public class ArrayListextends AbstractList ... protected transient int modCount = 0;
modCount是AbstractList的成員變量,ArrayList繼承下來了.所以modCount代表ArrayList的實(shí)際長度.
當(dāng)我們在iterator的迭代過程中改變了ArrayList的長度,就導(dǎo)致modCount變了,而expectedModCount 沒有變,導(dǎo)致不相等報(bào)錯(cuò)
可是為什么用iterator的remove方法就不報(bào)錯(cuò)呢,我們看Remove方法():
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
可以看到,ArrayList在刪除元素后,expectedModCount = modCount;重新賦值,讓這兩個(gè)值相等了.所以,remove方法不會(huì)拋出這個(gè)異常
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67499.html
摘要:單線程的迭代過程中刪除集合元素以上代碼會(huì)出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時(shí)調(diào)用了這個(gè)是調(diào)用返回的對(duì)象這個(gè)對(duì)象的方法如下圖方法首先它會(huì)調(diào)用這個(gè)方法這個(gè)方法很簡單就是比較這兩個(gè)值是不是相等不相等就拋出異常如下圖這兩個(gè)值為什么會(huì)不相 單線程的Iterator迭代過程中刪除集合元素 public class TestIterator { public static voi...
摘要:單線程的迭代過程中刪除集合元素以上代碼會(huì)出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時(shí)調(diào)用了這個(gè)是調(diào)用返回的對(duì)象這個(gè)對(duì)象的方法如下圖方法首先它會(huì)調(diào)用這個(gè)方法這個(gè)方法很簡單就是比較這兩個(gè)值是不是相等不相等就拋出異常如下圖這兩個(gè)值為什么會(huì)不相 單線程的Iterator迭代過程中刪除集合元素 public class TestIterator { public static voi...
摘要:迭代器智能嗎第一步,將列表中的根節(jié)點(diǎn)找出來。源碼翻開中迭代器的源碼。在迭代器對(duì)象執(zhí)行操作之前,都會(huì)執(zhí)行方法,以判斷當(dāng)前操作下是否安全。 引言 ConcurrentModificationException這個(gè)異常大家都很熟悉,當(dāng)在forEach進(jìn)行刪除時(shí)都會(huì)出現(xiàn)該異常。 如果你還不了解,請參考澍澍的博客:關(guān)于在list循環(huán)的過程中進(jìn)行刪除的處理 - 晨澍的博客 showImg(http...
摘要:迭代器智能嗎第一步,將列表中的根節(jié)點(diǎn)找出來。源碼翻開中迭代器的源碼。在迭代器對(duì)象執(zhí)行操作之前,都會(huì)執(zhí)行方法,以判斷當(dāng)前操作下是否安全。 引言 ConcurrentModificationException這個(gè)異常大家都很熟悉,當(dāng)在forEach進(jìn)行刪除時(shí)都會(huì)出現(xiàn)該異常。 如果你還不了解,請參考澍澍的博客:關(guān)于在list循環(huán)的過程中進(jìn)行刪除的處理 - 晨澍的博客 showImg(http...
摘要:源碼分析構(gòu)造方法有兩個(gè)構(gòu)造方法,一個(gè)是無參,另一個(gè)需傳入初始容量值。所以我們可以把上面的代碼轉(zhuǎn)換一下,等價(jià)于下面形式這個(gè)時(shí)候,我們再去分析一下的迭代器源碼就能找出原因。原因是刪除元素后,元素計(jì)數(shù)器,而迭代器中的也等于,從而導(dǎo)致返回。 1.概述 ArrayList 是一種變長的集合類,基于定長數(shù)組實(shí)現(xiàn)。ArrayList 允許空值和重復(fù)元素,當(dāng)往 ArrayList 中添加的元素?cái)?shù)量大于...
閱讀 3914·2021-09-10 11:22
閱讀 2385·2021-09-03 10:30
閱讀 3699·2019-08-30 15:55
閱讀 1970·2019-08-30 15:44
閱讀 870·2019-08-30 15:44
閱讀 620·2019-08-30 14:04
閱讀 3079·2019-08-29 17:18
閱讀 1300·2019-08-29 15:04