天天看點

使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

點選上方 "程式員小樂"關注, 星标或置頂一起成長

每天淩晨00點00分, 第一時間與你相約

每日英文

All problems, and ultimately is a matter of time. All the worry, in fact is a bother.

一切問題,最終都是時間問題。一切煩惱,其實都是自尋煩惱。

每日掏心話

累了,那就停下來,拍一拍灰塵,讓心靈重歸潔淨。昨天是今天的曆史;今天是明天的曆史;今天也是昨天的曆史;明天也是今天的曆史。

來自:Alice_qixin | 責編:樂樂

連結:blog.csdn.net/Alice_qixin/article/details/80256882

使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

程式員小樂(ID:study_tech)

第 916 次推文  圖源:百度

往日回顧:真贊!IDEA中這麼玩MyBatis,讓編碼速度飛起!

   正文   

先來看一下下面的樣例是否符合你的問題場景

list中根據判斷條件符合的就remove掉一個資料

 public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");

        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }}
           

結果是什麼?

結果是一下。根據以上代碼,希望得到的結果是 cde 但是運作結果是bcde那麼問題來了為什麼會得到一下結果呢

使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

先看一下list remove的源碼

// 删除ArrayList指定位置的元素
    public E remove(int index) {
        RangeCheck(index);//檢查index是否超出list大小範圍,否則抛出異常
        modCount++;
        E oldValue = (E) elementData[index];//elementData是實作list的數組
        int numMoved = size - index - 1;//當執行删除操作是後面的元素全部向前面移動一位
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
        elementData[--size] = null;
        return oldValue;
    }
    // 删除ArrayList的指定元素
    public boolean remove(Object o) {
        if (o == null) {
          for (int index = 0; index < size; index++)
             if (elementData[index] == null) {
                 fastRemove(index);
                return true;
            }
        } else {
            for (int index = 0; index < size; index++)
              if (o.equals(elementData[index])) {
                  fastRemove(index);
                  return true;
              }
        }
        return false;
   }
  //快速删除第index個元素
  private void fastRemove(int index) {
        modCount++;  
        int numMoved = size - index - 1;  
        if (numMoved > 0)  
            System.arraycopy(elementData, index+1, elementData, index,  
                             numMoved);  
        elementData[--size] = null; 
   } 
           

源碼可知,List在删除指定位置的對象時,執行删除操作是後面的元素全部向前面移動一位

因為,當你remove掉一個對象時,list的就少了一個 index 0的被remove了,之前index 1的資料就自動變為index 0了。arrayList是有順序數組,從0開始。如果從前開始删除實際上就相當于跳着删除了。

解決辦法1:

每次删除之後i--自動傳回到上一個index開始

    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");

        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                    i--;
                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}
           

使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

第二種解決方法

倒着删除從後往前周遊删除,從index大的往index小的删

    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);


        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");

        for (int i = list.size()-1; i >= 0; i--) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);

                }
            }


        }

        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}
           
使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

此問題,本人僅在remove對象時發現到此錯誤。當list裡面是基本類型資料時并沒有發生以上問題。在此記好。僅供參考

使用List中的remove方法遇到的坑,我不信你沒有踩過坑!

歡迎在留言區留下你的觀點,一起讨論提高。如果今天的文章讓你有新的啟發,歡迎轉發分享給更多人。歡迎加入程式員小樂技術交流群,在背景回複“加群”或者“學習”即可。

猜你還想看

阿裡、騰訊、百度、華為、京東最新面試題彙集

一文帶你了解 MySQL 中的各種鎖機制!

設計一個成功的微服務,堪稱必備的9個基礎知識

關注訂閱号「程式員小樂」,收看更多精彩内容