您的位置:首页 > 编程语言 > Java开发

ConcurrentModificationException异常解决

2015-09-07 21:57 603 查看
最近遇到了ConcurrentModificationException异常,根据条件remove List 中的值,源码简化如下:

public class Demo {
public static void main(String[] args) {
//new 一个List<String>
List<String> strList = new ArrayList<String>();
//循环插入值
for(int i=0;i<20;i++){
strList.add("string"+i);
}

for(String temp:strList){
//如果字符串包含“1”,则 remove,此处发生ConcurrentModificationException异常
if(temp.contains("1")){
strList.remove(temp);
}
}

for(String str:strList){
System.out.println(": "+str);
}
}
}


运行以上代码发生ConcurrentModificationException异常,查了之后,发现是因为for each 循环时用了迭代器,而remove操作则改变了现有的 List,所以发生了ConcurrentModificationException异常;

那么,我修改成如下代码:

for(int i= 0;i<strList.size();i++){
//如果字符串包含“1”,则 remove
String temp = strList.get(i);
if(temp.contains("1")){
strList.remove(temp);
}
}


运行结果:

: string0
: string2
: string3
: string4
: string5
: string6
: string7
: string8
: string9
: string11
: string13
: string15
: string17
: string19


很明显结果不对,原因是在对 List 进行 remove 操作是,List 的 size 是动态变化的, 所以得出的结果不对。

最后修改代码如下:

//新建一个临时List 装入符合条件的值
List<String> removeList = new ArrayList<String>();
for(int i= 0;i<strList.size();i++){
//如果字符串包含“1”,则 remove
String temp = strList.get(i);
if(temp.contains("1")){
removeList.add(temp);
}
}
//因为java是地址传递,所以 strList 和 removeList 里面的对象都是指的同一对象;这里移除的是对地址的引用
strList.removeAll(removeList);


运行结果:

: string0
: string2
: string3
: string4
: string5
: string6
: string7
: string8
: string9


虽然只是一个很小的 bug,也并不复杂,但是这也考校了编码人员的编码功底,特此留下笔记,以免日后再次犯同样的错误。

小生乃菜鸟一枚,如若写的有差池或各位有更好的方法,还望各位提出,大家共同进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息