Java碼農必須掌握的迴圈刪除List元素的正確方法

茅坤寶駿氹發表於2018-05-02

轉載自 Java碼農必須掌握的迴圈刪除List元素的正確方法

 

 首先看下下面的各種刪除list元素的例子

public static void main(String[] args) {

        List<String> list = new ArrayList<>(Arrays.asList("a1", "ab2", "a3", "ab4", "a5", "ab6", "a7", "ab8", "a9"));

        /**
         * 報錯
         * java.util.ConcurrentModificationException
         */
        for (String str : list) {
            if (str.contains("b")) {
                list.remove(str);
            }
        }

        /**
         * 報錯:下標越界
         * java.lang.IndexOutOfBoundsException
         */
        int size = list.size();
        for (int i = 0; i < size; i++) {
            String str = list.get(i);
            if (str.contains("b")) {
                list.remove(i);
            }
        }

        /**
         * 正常刪除,每次呼叫size方法,損耗效能,不推薦
         */
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            if (str.contains("b")) {
                list.remove(i);
            }
        }

        /**
         * 正常刪除,推薦使用
         */
        for (Iterator<String> ite = list.iterator(); ite.hasNext();) {
            String str = ite.next();
            if (str.contains("b")) {
                ite.remove();
            }
        }

        /**
         * 報錯
         * java.util.ConcurrentModificationException
         */
        for (Iterator<String> ite = list.iterator(); ite.hasNext();) {
            String str = ite.next();
            if (str.contains("b")) {
                list.remove(str);
            }
        }
    }

報異常IndexOutOfBoundsException我們很理解,是動態刪除了元素導致陣列下標越界了。

ConcurrentModificationException呢?

其中,for(xx in xx)是增強的for迴圈,即迭代器Iterator的加強實現,其內部是呼叫的Iterator的方法,為什麼會報ConcurrentModificationException錯誤,我們來看下原始碼

取下個元素的時候都會去判斷要修改的數量和期待修改的數量是否一致,不一致則會報錯,而通過迭代器本身呼叫remove方法則不會有這個問題,因為它刪除的時候會把這兩個數量同步。搞清楚它是增加的for迴圈就不難理解其中的奧祕了。

 

相關文章