java - 仅当列表大小大于 2 时,才会发生使用 foreach 从 arraylist 中删除对象的异常

标签 java arraylist

我有下面的类,用于检查使用 foreach 循环从数组列表中删除对象

import java.util.ArrayList;

    public class CheckArrayList {
        /**
         * @return the a
         */
        public int getA() {
            return a;
        }

        /**
         * @param a
         *            the a to set
         */
        public void setA(int a) {
            this.a = a;
        }

        /**
         * @return the b
         */
        public int getB() {
            return b;
        }

        /**
         * @param b
         *            the b to set
         */
        public void setB(int b) {
            this.b = b;
        }

        int a;
        int b;

        public static void main(String[] args) {
            try {
                CheckArrayList checkArrayList1 = new CheckArrayList();
                checkArrayList1.setA(10);
                checkArrayList1.setB(20);

                CheckArrayList checkArrayList2 = new CheckArrayList();
                checkArrayList2.setA(30);
                checkArrayList2.setB(40);

                ArrayList<CheckArrayList> aList = new ArrayList<CheckArrayList>();

                aList.add(checkArrayList1);
                aList.add(checkArrayList2);

                System.out.println("size of list before iterate = " + aList.size());
                for (CheckArrayList checkArrayList : aList) {
                    aList.remove(checkArrayList);
                    System.out.println("inside loop");
                }
                System.out.println("size of list after iterate = " + aList.size());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

在执行上述操作时,没有显示任何异常,但它只进入循环一次。

如果我向 ist 添加一个对象并执行相同的操作,它会显示 java.util.ConcurrentModificationException

import java.util.ArrayList;

public class CheckArrayList {
    /**
     * @return the a
     */
    public int getA() {
        return a;
    }

    /**
     * @param a
     *            the a to set
     */
    public void setA(int a) {
        this.a = a;
    }

    /**
     * @return the b
     */
    public int getB() {
        return b;
    }

    /**
     * @param b
     *            the b to set
     */
    public void setB(int b) {
        this.b = b;
    }

    int a;
    int b;

    public static void main(String[] args) {
        try {
            CheckArrayList checkArrayList1 = new CheckArrayList();
            checkArrayList1.setA(10);
            checkArrayList1.setB(20);

            CheckArrayList checkArrayList2 = new CheckArrayList();
            checkArrayList2.setA(30);
            checkArrayList2.setB(40);

            CheckArrayList checkArrayList3 = new CheckArrayList();
            checkArrayList3.setA(30);
            checkArrayList3.setB(40);

            ArrayList<CheckArrayList> aList = new ArrayList<CheckArrayList>();

            aList.add(checkArrayList1);
            aList.add(checkArrayList2);
            aList.add(checkArrayList3);

            System.out.println("size of list before iterate = " + aList.size());
            for (CheckArrayList checkArrayList : aList) {
                aList.remove(checkArrayList);
                System.out.println("inside loop");
            }
            System.out.println("size of list after iterate = " + aList.size());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果arralist大小等于2,为什么它不显示异常?

最佳答案

要回答为什么它不会在 2 个元素上抛出错误,您必须查看 foreach 循环实际执行的操作。for(Type some:myList) 编译为如下内容:

Iterator<Type> iter = myList.iterator();
while(iter.hasNext()){
     Type something= iter.next()
     //your code
}

现在查看ArrayList的源代码以了解实际实现。 hasNext() 的代码是:

return cursor != size; //cursor is the current position in the list

因此,当您删除循环中的元素时,size 现在为 1。当它查看是否有更多元素时,它将返回 false,因为它认为该元素位于循环的末尾。 ArrayList,并在此时停止执行循环。

现在看看 next() 的代码:

public E next() {
        checkForComodification();
        //more code
}

这是实际检查修改的地方,因此当 size 为 3 时,它将执行第二次迭代,当调用 next() 获取第二个元素时,它将抛出异常因为您已在迭代器之外修改了 ArrayList。

关于java - 仅当列表大小大于 2 时,才会发生使用 foreach 从 arraylist 中删除对象的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20040015/

相关文章:

java - 无法将 JSONObjects 添加到数组中

java - 按字母顺序排序数组列表时遇到问题

java - 循环中的 PathTransition

java - libGDX 如果用户在触摸后移动手指,如何停止 touchUp 注册

java - 放弃控制权 : machine code generation vs memory layout?

java - GUI - actionListener 方法

java - Stream.skip 行为与无序终端操作

java - ArrayLists 对象,如何从对象中添加/删除它们?

java - 如何列出 put 方法中的参数?

java - 文件处理的资源泄漏,try with resources VS try-catch-finally with file.close()