最近看同事寫了一個(gè)方法,在list循環(huán)里面修改list,以我的經(jīng)驗(yàn),肯定是會(huì)報(bào)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
結(jié)果,我同事的代碼神奇的通過了單元測(cè)試,我也很納悶,這是為啥,于是開始了自己的一番研究,經(jīng)過幾次調(diào)試,發(fā)現(xiàn)在集合最后一個(gè)處理的時(shí)候是不會(huì)出錯(cuò)的。
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)) { //和上面只改動(dòng)了這里的3
list.remove(i);
list.add("0");
}
}
System.out.println(list2);
}
返回 [1, 2, 0] 沒出錯(cuò)
然后馬上回去看了看同事的代碼,他這里并不是元素的最后一個(gè),但加了一個(gè)return跳出循環(huán)了,我也試了一下。
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;//跳出循環(huán)
}
}
System.out.println(list2);
}
返回 [1, 3, 0]
這樣居然就通了,也就是說,在集合處理的時(shí)候,如果是在最后一次循環(huán)中修改了集合的狀態(tài)是不會(huì)報(bào)錯(cuò)的。當(dāng)然,一般是不建議這么寫的啦,如果平時(shí)業(yè)務(wù)需求真的要用的這種操作,可以將ArrayList替換成CopyOnWriteArrayList。