最近看同事写了一个方法,在list循环里面修改list,以我的经验,肯定是会报ConcurrentModificationException异常的,比如这样:
private List<String> list = new ArrayList<>();
@Test
public void test2() {
list.add("1");
list.add("2");
list.add("3");
for (String i : list) {
if ("2".equals(i)) {
list.remove(i);
list.add("0");
}
}
System.out.println(list2);
}
返回java.util.ConcurrentModificationException
结果,我同事的代码神奇的通过了单元测试,我也很纳闷,这是为啥,于是开始了自己的一番研究,经过几次调试,发现在集合最后一个处理的时候是不会出错的。
private List<String> list = new ArrayList<>();
@Test
public void test2() {
list.add("1");
list.add("2");
list.add("3");
for (String i : list) {
if ("3".equals(i)) { //和上面只改动了这里的3
list.remove(i);
list.add("0");
}
}
System.out.println(list2);
}
返回 [1, 2, 0] 没出错
然后马上回去看了看同事的代码,他这里并不是元素的最后一个,但加了一个return跳出循环了,我也试了一下。
private List<String> list = new ArrayList<>();
@Test
public void test2() {
list.add("1");
list.add("2");
list.add("3");
for (String i : list) {
if ("2".equals(i)) {
list.remove(i);
list.add("0");
break;//跳出循环
}
}
System.out.println(list2);
}
返回 [1, 3, 0]
这样居然就通了,也就是说,在集合处理的时候,如果是在最后一次循环中修改了集合的状态是不会报错的。当然,一般是不建议这么写的啦,如果平时业务需求真的要用的这种操作,可以将ArrayList替换成CopyOnWriteArrayList。