初始化
List<String> list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
● 错误删除方法(for-each)发生java.util.ConcurrentModificationException异常
for (String s : list){
if ("a".equals(s)){
list.remove(s);
}
}
● 错误删除方法(fori正序循环——未修改索引)可能不影响结果,但有漏洞,会跳过下一个元素
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
if("a".equals(s)){
list.remove(i);
}
}
System.out.println(list);
运行结果[b, c, d]
,看似正确,但其实跳过了b元素比对,当修改代码同时删除b,则发现问题
for(int i=0; i<list.size(); i++){
if(list.get(i).equals("a") || list.get(i).equals("b")){
list.remove(i);
}
}
System.out.println(list);
运行结果[b, c, d]
,显然不是我们期望的,这是由于索引前移,a移除后,b的索引由1变0,c由2变1,i++后比对索引1时,跳过了前移的b,直接比对c。正序的正确写法和其他删除方法如下:
正确方法一:正序删除——修正索引
for(int i=0; i<list.size(); i++){
if(list.get(i).equals("a") || list.get(i).equals("b")){
list.remove(i);
i--; // 修正索引
}
}
正确方法二:倒序删除——不需要修正
for(int i = list.size() - 1; i >= 0; i--){
String s = list.get(i);
if("a".equals(s) || list.get(i).equals("b")){
list.remove(s);
}
}
正确方法三:迭代器Iterator删除(推荐)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String str = iterator.next();
if(str.equals("a") || str.equals("b")){
iterator.remove();
}
}
正确方法四:list.removeIf()
list.removeIf((s)->"a".equals(s) || "b".equals(s));
正确方法五:CopyOnWriteArrayList的 remove()方法
CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<String>(list);
for (String s : cowList) {
if ("a".equals(s) || "b".equals(s) ) {
cowList.remove(s);
}
}
System.out.println(cowList);