为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

喵喵时光机 2019-06-28 17:18:46
为什么在本例中我没有得到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);             }         }     }}
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

原因如下:正如Javadoc中所说的:

这个类的迭代器和listIterator方法返回的迭代器是快速失败的:如果列表在创建迭代器之后的任何时候进行了结构上的修改,那么除了通过迭代器自己的Remove或Add方法,迭代器将抛出一个ConcurrentModificationException。

此检查是在next()迭代器的方法(从堆栈跟踪中可以看到)。但我们会到达next()方法只在hasNext()传递为真,这是每个人所调用的,以检查边界是否满足。在删除方法中,当hasNext()检查它是否需要返回另一个元素,它将看到它返回了两个元素,现在,在删除一个元素之后,列表只包含两个元素。因此,所有的都是桃子,我们已经完成了迭代。不会对并发修改进行检查,因为这是在next()方法,该方法从未被调用。

接下来我们进入第二个循环。删除第二个数字后,hasNext方法将再次检查是否可以返回更多的值。它已经返回了两个值,但是列表现在只包含一个。但这里的代码是:

public boolean hasNext() {
        return cursor != size();}

1!=2,所以我们继续到next()方法,该方法现在认识到有人一直在处理列表并触发异常。

希望这能澄清你的问题。

摘要

List.remove()不会扔ConcurrentModificationException当它从列表中移除第二个最后一个元素时。


查看完整回答
反对 回复 2019-06-28
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

的副本中删除某物的一种方法。Collection(不包括收款本身),如果适用的话。Clone原始集合,以便通过Constructor.

此异常可能由检测到对象的并发修改的方法引发,而这种修改是不允许的。

对于你的具体情况,首先,我不认为final是一种考虑到您打算修改过去声明的列表的方法。

private static final List<Integer> integerList;

还可以考虑修改副本而不是原始列表。

List<Integer> copy = new ArrayList<Integer>(integerList);for(Integer integer : integerList) {
    if(integer.equals(remove)) {                
        copy.remove(integer);
    }}


查看完整回答
反对 回复 2019-06-28
?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

前向/迭代器方法在移除项时不起作用。您可以在没有错误的情况下删除元素,但是当您尝试访问已删除的项时,您将得到一个运行时错误。您不能使用迭代器,因为PUSY显示它会导致ConcurrentModificationException,所以使用正则for循环代替,但是后退一步。

List<Integer> integerList;integerList = new ArrayList<Integer>();integerList.add(1);integerList.add(2);integerList.add(3);int size= integerList.size();//Item to removeInteger remove = Integer.valueOf(3);

解决办法:

如果要删除List元素,则按反向顺序遍历数组。只需向后遍历列表,就可以避免访问已删除的项,该项将删除异常。

//To remove items from the list, start from the end and go backwards through the arrayList//This way if we remove one from the beginning as we go through, then we will avoid getting a runtime error//for java.lang.IndexOutOfBoundsException or java.util.ConcurrentModificationException as when we used the iteratorfor (int i=size-1; i> -1; i--) {
    if (integerList.get(i).equals(remove) ) {
        integerList.remove(i);
    }}


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 703 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号