平时你们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而出错;若是要在遍历时删除,最安全就是用迭代器。