当前位置: 首页 > 面试题库 >

为什么在此示例中没有得到java.util.ConcurrentModificationException?

阎宾实
2023-03-14
问题内容

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

在下面的代码示例中,我不明白为什么List.removemain方法抛出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);
            }
        }
    }
}

问题答案:

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

此类的迭代器和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间以任何方式对列表进行结构修改,除非通过迭代器自己的remove或add方法,否则迭代器将抛出ConcurrentModificationException

该检查是在next()迭代器的方法中完成的(如你在stacktrace中所看到的)。但是,next()只有在hasNext()传递的结果为true时,我们才能实现该方法,这是每个方法调用此方法以检查是否满足边界的要求。在你的remove方法中,当hasNext()检查是否需要返回另一个元素时,将看到它返回了两个元素,现在在删除一个元素之后,列表仅包含两个元素。因此,一切都变桃了,我们已经完成了迭代。不会进行并发修改检查,因为这是在next()从未调用过的方法中完成的。

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

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

1!= 2,因此我们继续执行next()方法,该方法现在意识到有人一直在弄乱列表并触发异常。

希望能解决你的问题。

摘要
List.remove()ConcurrentModificationException从列表中删除倒数第二个元素时不会抛出该异常。



 类似资料:
  • 问题内容: 我知道静态方法在类级别。因此,我知道我不需要创建实例来调用静态方法。但我也知道我可以将静态方法(如LIKE)称为实例方法。这是我感到困惑的地方,因为我期望从null对象调用静态方法(就像在调用实例方法中一样)。我真的很感谢一些解释,为什么我错了一个期望。 这是示例代码: 问题答案: 通过实例调用静态方法不需要实例存在。只要编译器能够确定变量的类型,它就可以在评估表达式并丢弃结果后静态进

  • 问题内容: 我发现最高的素数除以num,如程序所示,数组和 解决此问题的最佳方法是什么? 我正在解决这个问题, 检查因子直到num / 2, 全部推入一个数组, 检查最后一个元素…… 首先,我需要做更多的事情,但是我仍处于起步阶段。 问题答案: 看来您正在寻找的所有除数;其中之一将是最大的主要因素。仅两个相关事实应有助于使问题对于小数可解决: 1.如果是除数,则也是如此。 2.您不需要检查任何大于

  • 问题内容: Apple编写的有关SwiftUI的教程使用美元符号来绑定数据,而我在查找有关SwiftUI中此数据绑定的更多信息时遇到了麻烦。 您可以使用$前缀来访问对状态变量或其属性之一的绑定。 这是某种类型参数吗?那是使用“&”号传递的。 问题答案: 该是与物业代表一起使用。 它 不是运算符 ,而是 前缀 (感谢@matt!)。 有关属性委托的更多信息,请参见此Swift Evolution 文

  • 问题内容: 试图弄清楚React的基础知识。 查看此页面上的第二个示例:https : //facebook.github.io/react/ 我看到tick()函数设置Timer类的状态,将前一个值加1。 但是,当我尝试实现自己的简单Counter类时,它失败了,并且出现控制台错误,提示 无法读取未定义的setState属性。 一些谷歌搜索显示我必须将其绑定到增量函数。但是,为什么在我看到的第一

  • 这与 R- 查看具有任何 NA 的所有列名称有关 我比较了data.frame和data.table版本,发现data.table慢了10倍。这与大多数使用data.table的代码相反,后者确实比data.frame版本快得多。 预先设置: 可能是什么原因?

  • 问题内容: 我正在编写一个简单的项目,一个使用Swing编写的业务应用程序,它使用Hibernate作为后端。我来自Spring,这为我提供了使用hibernate和事务的简便方法。无论如何,我设法让Hibernate工作。昨天,在编写一些代码从数据库中删除bean的同时,我得到了以下信息: 删除代码很简单: 我的是: 其他详细信息:仅在关闭应用程序时,我才会在代码中关闭hibernate会话。这