記一次list循環刪除元素的突發事件!

事情是這樣的,因爲想再回顧一下基礎,就寫了一個main函數,裏面循環刪元素的代碼。以下:java

List<String> a = new ArrayList<String>();
a.add("a");
a.add("b");
for (String temp : a)
{
if("a".equals(temp)){
a.remove(temp);
}
}
System.out.println( a.toString()); 函數

那麼正常狀況下我預期是會報異常 :Exception in thread "main" java.util.ConcurrentModificationExceptionspa

可是,結果確是正常刪除了。。並且打印出告終果~~着實嚇了我一跳,沒有異常。。。而後就修改了代碼將刪除a換成了b,結果是報了異常了!!!哎,這下就納悶了,這是爲何呢!!!code

而後就看了下remove方法的源碼~發現報異常的緣由是每當咱們add的時候modcount就會加1,這個時候,還有一個expectedModCount 默認是將modcount 賦值給他,每當咱們刪除了一個元素那麼remove 方法會先調用checkForComodification()再調用裏面的一個fastremove方法,在這個方法裏面會再執行modCount++; rem

在checkForComodification方法中進行的操做是:源碼

final  void  checkForComodification() {
     if  (modCount != expectedModCount)
     throw  new  ConcurrentModificationException();
}
若是modCount不等於expectedModCount,則拋出ConcurrentModificationException異常。
 
那爲何第一個能夠正常刪呢~這個時候我又增長了若干元素,通過驗證得知,在整個集合中的倒數第二個位置的元素,進行刪除操做是不會報異常的,爲何呢?
修改代碼,在每次循環時打印輸出元素

List<String> a = new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
a.add("d");
a.add("e");
for (String temp : a)
{
if("d".equals(temp)){
a.remove(temp);
}
System.out.println( temp.toString());
}
System.out.println( a.toString());

}io

這個時候的輸出結果爲:ast

a
b
c
d
[a, b, c, e]class

看結果是沒有再循環e刪除完d就結束了~thread

因爲當刪除完d元素後,後面的元素會自動向前移動,而後把最後的元素置位null,也就是告訴gc能夠回收了。那麼這個時候整個的size就變成了4,固到此就會認爲整個循環結束,因此沒有報異常。。。

相關文章
相關標籤/搜索