平時你們for循環應該用的很多,特別是加強for循環,簡單快捷。可是在加強for中作刪除操做,卻會拋出java.util.ConcurrentModificationException,一塊兒來看下。java
上面的代碼,在for循環執行完if中的remove,遍歷下一個元素時便會拋出java.util.ConcurrentModificationException。到底在for (String s : list)中發生了什麼呢。安全
ArrayList中有一個內部類Itr,它繼承了Iterator接口。當第一次遍歷加強for循環時,會建立一個Itr對象,注意下圖紅框的部分,變量modCount屬於ArrayList,用來記錄ArrayList被修改的次數,賦值給了Itr類的變量expectedModCount。
而後依次調用Itr的hasNext()和next()方法,取出ArrayList中的元素賦值給for中的變量,注意紅框的方法checkForComodification()。3d
當執行list.remove(s)時,實則調用其內部的fastRemove(index)作的刪除操做,同時modCount++,可是並無從新賦值給Itr類的變量expectedModCount。那麼,當遍歷下一個元素調用checkForComodification()方法時,if中的條件就會成立,而後就會拋出ConcurrentModificationException異常。
既然加強for循環中的remove操做會拋異常,那麼在普通for循環和迭代器循環中作remove也會拋異常嗎?對象
普通for循環blog
普通for循環調用的是remove(int index)方法,不會拋異常,可是須要注意,繼承
1. 若是將for中的i < list.size()替換成i < length,會拋出IndexOutOfBoundsException接口
2. 在list.remove(i)後,下一次遍歷前,此時i表示第i+1個元素rem
迭代器循環get
迭代器循環調用的是Itr類的remove(int index)方法,不會拋異常,緣由是其內部也是調用的ArrayList的remove(int index)方法,可是在以後,有給expectedModCount從新賦值。同步
因此
加強for循環,實際上仍是迭代器遍歷,可是remove操做並無同步變量,會致使異常;普通for雖然沒有異常,可是在remove後可能會忽略下標+1而出錯;若是要在遍歷時刪除,最安全就是用迭代器。