Java集合ConcurrentModificationException陷阱

最近看同事寫了一個(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。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容