Java中ArrayList remove會遇到的坑


前言

平時最常用的莫過於ArrayListHashMap了,面試的時候也是問答的常客。先不去管容量、負載因子什么的,就是簡單的使用也會遇到坑。

Remove 元素

經常遇到的一個場景是:遍歷list, 然后找到合適條件的給刪除掉,比如刪除所有的偶數。

@Test
public void testRemove2(){
    List<Integer> integers = new ArrayList<>(5);
    integers.add(1);
    integers.add(2);
    integers.add(2);
    integers.add(4);
    integers.add(5);

    for (int i = 0; i < integers.size(); i++) {
        if (integers.get(i)%2==0){
            integers.remove(i);
        }
    }

    System.out.println(integers);
}

看起來好像沒問題,加入面試的時候當面問:輸出結果是什么?再問真不會報錯嗎?再問結果是什么?

  • 報錯
  • 結果是空list
  • 結果是[1, 2, 5]

List.remove()有兩個,一個 public E remove(int index),一個是public boolean remove(Object o) ,那下面的結果是什么:

@Test
public void testRemove(){
    ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4);
    System.out.println(integers);
    integers.remove(1);
    System.out.println(integers);
}
  • [1, 3, 4]

經常會使用一個Arrays.asList的API, 那么下面的結果是什么:

@Test
public void testRemove3(){
    List<String> list = Arrays.asList("a","b");
    list.add("c");
    System.out.println(list);
}
  • 報錯: java.lang.UnsupportedOperationException

使用foreach是否可以實現剛開始的問題

@Test
public void testRemove4(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    for (String string : strings) {
        strings.remove(string);
    }
}
  • 否,報錯java.util.ConcurrentModificationException

為了性能問題,我們推薦把list.size的計算提取出來

@Test
public void testRemove5(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    int size = strings.size();
    for (int i = 0; i < size; i++) {
        strings.remove(i);
    }

}
  • 報錯: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
  • 這是很好的習慣, 不像開頭那樣每次循環都計算一次size,而且按這種情況還可以再運行的時候報錯。文初的做法不報錯,但結果並不是我們想要的。

使用Iterator是不是就可以remove了


@Test
public void testRemove6(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        strings.remove(next);
    }

    System.out.println(strings);
}
  • 報錯: java.util.ConcurrentModificationException

正確的remove做法是什么

@Test
public void testRemove7(){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        iterator.remove();
    }

    System.out.println(strings);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM