面試掛在了 list.remove 數組下標位移

面試題:在一個集合中,有幾個隨機字符串,有些含有a,有些沒有a,用普通for循環遍歷,移除含有a字符的字符串,示例如下,請問最終的打印輸出結果是?

public static void main(String[] args) {
      List<String> list = new ArrayList<>();
       list.add("abc");
       list.add("afg");
       list.add("amf");
       list.add("mfg");
       list.add("age");
       list.add("ofh");

       for (int i= 0; i < list.size();i++){
           if(list.get(i).contains("a")){
               list.remove(i);
           }
       }

       for (String str : list) {
           System.out.println(str);
       }
}

實際結果:afg mfg ofh

結果中,竟然有字符串中含有a,它不是應該已經被移除了嗎?爲什麼會這樣呢?

解析:
在list集合遍歷的時候,每一次循環,指針都會向後移動一位(理解爲i從0開始,每次都會後移一位),但是,如果有元素被刪除了,那後面的所有元素都會順次向前移動一位(0索引的元素沒了,那後面的就會補過來啊),所以每次操作結果如下表:
在這裏插入圖片描述
是不是很直觀的可以看出,由於每次刪除元素後,數組下標會自動前移一位,導致存在落網之魚

如何解決這一問題呢?我們根據原理分析,既然每次刪除會造成數組下標前移一位,數據向前,那麼我們可以
1)防止下標前移造成的漏查

public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("abc");
        list.add("afg");
        list.add("amf");
        list.add("mfg");
        list.add("age");
        list.add("ofh");

        for (int i= 0; i < list.size();i++){
            if(list.get(i).contains("a")){
                list.remove(i);
                i--; //簡單的一行代碼,即每次刪除元素後,使下標前移一位,避免漏查
            }
        }

        for (String str : list) {
            System.out.println(str);
        }

    }

2)防止數據前移

public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("abc");
        list.add("afg");
        list.add("amf");
        list.add("mfg");
        list.add("age");
        list.add("ofh");

        for (int i = list.size() -1; i >=0 ; i--) { //從後往前查,從後面開始刪除,避免數據前移
            if(list.get(i).contains("a")){
                list.remove(i);
            }
        }

        for (String str : list) {
            System.out.println(str);
        }

    }

記住啦,下次面試還會有喲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章