那些年走過ArrayList迴圈remove的坑

lee_lgw發表於2021-09-09

這是一個java程式設計師邁向成功必定踩過的坑,在集合中迴圈remove,應如何避免?
首先上出錯程式碼
用增強版for迴圈

public static void main(String [] args){
     List<Integer> arrayList  = new ArrayList<Integer>();
     arrayList.add(1);
     arrayList.add(2);
     arrayList.add(3);
     arrayList.add(4);
     arrayList.add(5);
     //利用增強版for迴圈進行刪除
     for(Integer array:arrayList){
       if(array>2){
         arrayList.remove(array);
       }
     }
//異常
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at TestInterface1.main(TestInterface1.java:16)

//普通for迴圈

List<Integer> arrayList  = new ArrayList<Integer>();
     arrayList.add(10);
     arrayList.add(20);
     arrayList.add(30);
     arrayList.add(40);
     arrayList.add(50);
     //進行刪除
    for(int j =0 ;j<arrayList.size();j++){
      if(arrayList.get(j)>20){
        arrayList.remove(j);
      }
    }
    //輸出
    for(Integer array:arrayList){
      System.out.println(array);
    }
//結果
10 20 40

增強版說異常資訊說併發修改異常?小夥伴一下就慌了,
用普通版刪除不報錯但是,看結果是認真的嗎?大於20的都應該被刪除啊。

下面用正確的方法
1.迭代器

//迭代器進行刪除
     Iterator<Integer> iter =  arrayList.iterator();
     while(iter.hasNext()){
       if(iter.next()>20){
         iter.remove();
       }
     }
    //輸出
    for(Integer array:arrayList){
      System.out.println(array);
    }
    //結果
    10 20

小夥伴們肯定覺得很奇怪,為什麼前兩種不行?

  1. 第一種不行的原因在於當刪除一個元素時,下標已經發生了變化,控制符i已經不好使,不理解的看這段程式碼
 List<Integer> arrayList  = new ArrayList<Integer>();
     arrayList.add(10);
     arrayList.add(20);
     arrayList.add(30);
     arrayList.add(40);
     arrayList.add(50);
     //迭代器進行刪除
    for(int i= 0;i<arrayList.size();i++){
      if(arrayList.get(i)>20){
        arrayList.remove(i);
        //刪除之後集合的原有位置發生變化,只能讓i減減進行獲取元素
        i--;
      }
    }
    //輸出
    for(Integer array:arrayList){
      System.out.println(array);
    }
    //結果 10 20
  1. 增強版fou迴圈不行的原因為, 增強版for迴圈內部採用的是迭代器實現的,但在對元素刪除時,其實用的是ArrayList的remove方法,故會產生併發修改異常,如圖
    iter.remove();為迭代器刪除時所用刪除方法
    arrayList.remove(array);用增強版for迴圈時呼叫的刪除方法,這個刪除方法是來源與ArrayList的刪除方法。

至此 為什麼不能在集合中迴圈刪除或新增 到此結束,如有不對,望提醒

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1020/viewspace-2823766/,如需轉載,請註明出處,否則將追究法律責任。

相關文章