一 ArrayList循环删除陷阱
模板测试代码如下:
public classArrayListRemove {public static voidmain(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add("bb");
list.add("bb");
list.add("ccc");
list.add("ccc");
list.add("ccc");
remove(list);//执行删除//打印列表元素
for(String s : list) {
System.out.println("element : " +s);
}
}public static void remove(ArrayListlist) {//TODO
}
}
1 错误写法一
public static void remove(ArrayListlist) {for (int i = 0; i < list.size(); i++) {if ("bb".equals(list.get(i))){
list.remove(i);
}
}
}
执行结果如下:
element : a
element : bb
element : ccc
element : ccc
element : ccc
可以发现,有一个"bb"的字符串没有被删除掉。
2 错误写法二
public static void remove(ArrayListlist) {for(String s : list) {if ("bb".equals(s)) {
list.remove(s);
}
}
}
执行结果如下:
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 com.dh.yjt.SpringBootDemo.test.Collection.ArrayListRemove.remove(ArrayListRemove.java:24)
at com.dh.yjt.SpringBootDemo.test.Collection.ArrayListRemove.main(ArrayListRemove.java:16)
发现抛出ConcurrentModificationException的异常。
3 问题分析
要分析产生上述错误现象的原因唯有翻一翻jdk的ArrayList源码,先看下ArrayList中的remove方法(注意ArrayList中的remove有两个同名方法,只是入参不同,这里看的是入参为Object的remove方法)是怎么实现的:
public booleanremove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {
fastRemove(index);return true;
}
}else{for (int index = 0; index < size; index++)if(o.equals(elementData[index])) {
fastRemove(index);return true;
}
}return false;
}
发现最终都会调用f