为什么在本例中我没有得到java.util.ConcurrentModificationExcep

为什么在本例中我没有得到java.util.ConcurrentModificationException?

注:我知道Iterator#remove()方法。

在下面的代码示例中,我不明白为什么List.remove在……里面main方法抛ConcurrentModificationException,但是remove方法。

public class RemoveListElementDemo {    
    private static final List<Integer> integerList;

    static {
        integerList = new ArrayList<Integer>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
    }

    public static void remove(Integer toRemove) {
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }

    public static void main(String... args) {                
        remove(Integer.valueOf(2));

        Integer toRemove = Integer.valueOf(3);
        for(Integer integer : integerList) {
            if(integer.equals(toRemove)) {                
                integerList.remove(integer);
            }
        }
    }}


喵喵时光机
浏览 704回答 3
3回答

潇潇雨雨

原因如下:正如Javadoc中所说的:这个类的迭代器和listIterator方法返回的迭代器是快速失败的:如果列表在创建迭代器之后的任何时候进行了结构上的修改,那么除了通过迭代器自己的Remove或Add方法,迭代器将抛出一个ConcurrentModificationException。此检查是在next()迭代器的方法(从堆栈跟踪中可以看到)。但我们会到达next()方法只在hasNext()传递为真,这是每个人所调用的,以检查边界是否满足。在删除方法中,当hasNext()检查它是否需要返回另一个元素,它将看到它返回了两个元素,现在,在删除一个元素之后,列表只包含两个元素。因此,所有的都是桃子,我们已经完成了迭代。不会对并发修改进行检查,因为这是在next()方法,该方法从未被调用。接下来我们进入第二个循环。删除第二个数字后,hasNext方法将再次检查是否可以返回更多的值。它已经返回了两个值,但是列表现在只包含一个。但这里的代码是:public&nbsp;boolean&nbsp;hasNext()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;cursor&nbsp;!=&nbsp;size();}1!=2,所以我们继续到next()方法,该方法现在认识到有人一直在处理列表并触发异常。希望这能澄清你的问题。摘要List.remove()不会扔ConcurrentModificationException当它从列表中移除第二个最后一个元素时。

红糖糍粑

的副本中删除某物的一种方法。Collection(不包括收款本身),如果适用的话。Clone原始集合,以便通过Constructor.此异常可能由检测到对象的并发修改的方法引发,而这种修改是不允许的。对于你的具体情况,首先,我不认为final是一种考虑到您打算修改过去声明的列表的方法。private&nbsp;static&nbsp;final&nbsp;List<Integer>&nbsp;integerList;还可以考虑修改副本而不是原始列表。List<Integer>&nbsp;copy&nbsp;=&nbsp;new&nbsp;ArrayList<Integer>(integerList);for(Integer&nbsp;integer&nbsp;:&nbsp;integerList)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if(integer.equals(remove))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy.remove(integer); &nbsp;&nbsp;&nbsp;&nbsp;}}

凤凰求蛊

前向/迭代器方法在移除项时不起作用。您可以在没有错误的情况下删除元素,但是当您尝试访问已删除的项时,您将得到一个运行时错误。您不能使用迭代器,因为PUSY显示它会导致ConcurrentModificationException,所以使用正则for循环代替,但是后退一步。List<Integer>&nbsp;integerList;integerList&nbsp;=&nbsp;new&nbsp;ArrayList<Integer>();integerList.add(1);integerList.add(2);integerList.add(3);int&nbsp;size=&nbsp;integerList.size();//Item&nbsp;to&nbsp;removeInteger&nbsp;remove&nbsp;=&nbsp;Integer.valueOf(3);解决办法:如果要删除List元素,则按反向顺序遍历数组。只需向后遍历列表,就可以避免访问已删除的项,该项将删除异常。//To&nbsp;remove&nbsp;items&nbsp;from&nbsp;the&nbsp;list,&nbsp;start&nbsp;from&nbsp;the&nbsp;end&nbsp;and&nbsp;go&nbsp;backwards&nbsp;through&nbsp;the&nbsp;arrayList//This&nbsp;way&nbsp;if&nbsp;we&nbsp;remove&nbsp;one&nbsp;from&nbsp;the&nbsp;beginning&nbsp;as&nbsp;we&nbsp;go&nbsp;through,&nbsp;then&nbsp;we&nbsp;will&nbsp;avoid&nbsp;getting&nbsp;a&nbsp;runtime&nbsp;error//for&nbsp;java.lang.IndexOutOfBoundsException&nbsp;or&nbsp;java.util.ConcurrentModificationException&nbsp;as&nbsp;when&nbsp;we&nbsp;used&nbsp;the&nbsp;iteratorfor&nbsp;(int&nbsp;i=size-1;&nbsp;i>&nbsp;-1;&nbsp;i--)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(integerList.get(i).equals(remove)&nbsp;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;integerList.remove(i); &nbsp;&nbsp;&nbsp;&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java