仅当列表大小大于 2 时,才会使用 foreach 异常从数组列表中删除对象 [英] removing object from arraylist using foreach exception occurs only when the list size above 2

查看:29
本文介绍了仅当列表大小大于 2 时,才会使用 foreach 异常从数组列表中删除对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the below class for checking removing of object from arraylist by using foreach loop

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

if I add one more object to ist and doing same operation it showing 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 个元素上引发错误,您必须查看 for each 循环实际执行的操作.for(Type something:myList) 编译为:

To answer why it doesn't throw an error on 2 elements you have to look at what the for each loop actually does.for(Type something:myList) compiles to something like:

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

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

Now look at the source code for ArrayList for the actual implementation. The code for hasNext() is:

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

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

So when you remove the element in the loop, the size is now 1. When it looks to see if there are more elements it will return false because it thinks that is at the end of the ArrayList, and stops executing the loop at this point.

现在看next()的代码:

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

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

This is where the actual checking for modification occurs, so when size is 3, it will execute the second iteration and when it calls next() to get the second element, it will thrown an exception because you have modified the ArrayList outside of the iterator.

这篇关于仅当列表大小大于 2 时,才会使用 foreach 异常从数组列表中删除对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆