在jdk5之后有5种遍历并删除的写法:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListRemoveTest { public static void main(String[] args) { ListRemoveTest test = new ListRemoveTest(); System.out.println("-1-使用jdk5.0以后的增强for循环去remove"); List<String> list = test.buildList(); try { for (String str : list) { list.remove(str); } } catch (Exception e) { // java.util.ConcurrentModificationException e.printStackTrace(); } System.out.println("-2-使用Iterator的remove"); list = test.buildList(); try { Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { iterator.next(); iterator.remove(); } } catch (Exception e) { // java.lang.IllegalStateException e.printStackTrace(); } System.out.println("-3-iterator遍历+list的remove"); try { list = test.buildList(); for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) { String str = (String) iterator.next(); list.remove(str); } } catch (Exception e) { // java.util.ConcurrentModificationException e.printStackTrace(); } System.out.println("-4-使用list的remove(int)方法. [由后向前删除]"); list = test.buildList(); for (int i = list.size(); i > 0; i--) { list.remove(i - 1); } System.out.println("-5-使用list的remove(int)方法. [由前向后删除]"); list = test.buildList(); for (int i = 0; i < list.size(); i++) { list.remove(0); } } private List<String> buildList() { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); return list; } }
运行结果:
-1-使用jdk5.0以后的增强for循环去remove java.util.ConcurrentModificationException -2-使用Iterator的remove -3-iterator遍历+list的remove at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:781) at java.util.ArrayList$Itr.next(ArrayList.java:753) at com.jdk.ListRemoveTest.main(ListRemoveTest.java:14) java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:781) at java.util.ArrayList$Itr.next(ArrayList.java:753) at com.jdk.ListRemoveTest.main(ListRemoveTest.java:39) -4-使用list的remove(int)方法. [由后向前删除] -5-使用list的remove(int)方法. [由前向后删除]
2,4,5运行正常,1,3抛出
java.util.ConcurrentModificationException
原因分析:
1,3都是因为list的长度改变,Iterator执行next()方法时,调用checkForComodification()时出错,1,3是同一个问题,这两个方法remove操作都是执行的是ArrayList中的remove方法,根本原因在于expectedModCount与modCount他们的不相等,由于执行了ArrayList中的remove(),modCount在每一次循环值会发生改变,而expectedModCount并没有发生,在执行checkForComodification()方法就会抛出异常。
2之所以正确运行是因为调用了Iterator的remove方法,4,5不会执行checkForComodification()操作,所以不会出现这种异常。
结论:
在执行remove()不要将ArrayList 与Iterator混合使用,单独使用Iterator以及ArrayList的删除都是OK的
注意事项:
在使用Iterator的时候,必须先调用next()来获取第一个元素,否则调用remove()的时候会抛IllegalStateException错误。