1. 程式人生 > 其它 >對集合中元素的刪除為什麼要使用迭代器

對集合中元素的刪除為什麼要使用迭代器

各種處理方式分析

1.在增強for迴圈中使用remove刪除

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        for (String s : list) {
            if (s.equals("5")) {
                list.remove(s);
            }
        }
        System.out.println(list);
    }

這裡會報一個併發修改異常

那麼這個異常是什麼導致的呢。首先我們要明白一點,增強for迴圈,在編譯過後遍歷是通過迭代器來實現,也正是這個實現方式,導致出現了問題。

2.普通for迴圈刪除

public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("f");
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals("d")) {
                list.remove(i);
            }
        }
        for (int j = 0; j < list.size(); j++) {
            System.out.println(list.get(j));
        }
    }


可以看到此時並沒有報錯,但是我們發現最終的list裡並沒有將所有的"d"刪除,並不是我們想要的結果,即這種方式刪除的時候,不會報錯,但是當遇到連續要刪除的值的時候,就會漏刪。因為當你刪除的時候,後面一個索引就往前移了一個,但是i的值還在增加,所以導致漏刪的情況。

3.正確方式:使用迭代器進行刪除

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("f");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (iterator.next().equals("d")) {
                iterator.remove();
            }
        }
        
        for (int j = 0; j < list.size(); j++) {
            System.out.println(list.get(j));
        }
    }


結果符合我們的預期哈

4.jdk1.8後的快捷方式

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("f");

        List<String> collect = list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return !s.equals("d");
            }
        }).collect(Collectors.toList());

        for (int j = 0; j < collect.size(); j++) {
            System.out.println(collect.get(j));
        }
    }


可以看到轉化為流之後使用filter方式很輕鬆的就達到了我們想要的結果。