【问题标题】:why does ListIterator.add does not throw ConcurrentModificationException but list.add below throw exception?为什么 ListIterator.add 不抛出 ConcurrentModificationException 但 list.add 下面抛出异常?
【发布时间】:2018-04-08 17:38:45
【问题描述】:

您好,我想了解 ListIterator 上的添加操作是如何工作的。我不明白为什么第 7 行允许我将项目添加到迭代器并且第 8 行抛出 ConcurrentModificationException。将项目添加到 ListIterator 与将项目添加到 List 有什么区别。两者都在努力实现相同的目标。

List<String> list = new ArrayList<String>();
list.add("hi");
list.add("whats up");
list.add("how are you");
list.add("bye");

ListIterator<String> i = list.listIterator();

while (i.hasNext()) {
    System.out.println(i.next());
    list.add("Sample"); // Line #7
    i.add("Test"); // Line #8
}
System.out.println(list);

【问题讨论】:

  • 标题正确吗? List.add 不会抛出 CME,ListIterator.add 会。标题另有说明。

标签: java data-structures


【解决方案1】:

List.add 将指定元素附加到此列表的末尾。

ListIterator.add 粗略地说“在当前位置之后”插入指定元素。更准确地说,该元素被插入到将由next()(如果有)返回的元素之前,以及在将由previous()(如果有)返回的元素之后。同样添加带有ListIterator.add 的元素不会产生ConcurrentModificationException

您得到ConcurrentModificationException,因为您在迭代列表迭代器时调用了list.add。这是由于fail-fast 功能:

这个类的iteratorlistIterator 方法返回的迭代器是fail-fast:如果列表在创建迭代器后的任何时候在结构上被修改,除了通过迭代器自己的removeadd 方法,迭代器会抛出一个ConcurrentModificationException。因此,面对并发修改,迭代器会快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。

这正是正在发生的事情。您直接修改列表(而不是通过迭代器自己的方法)。

【讨论】:

    猜你喜欢
    • 2010-12-09
    • 2014-09-11
    • 2013-02-12
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2011-01-04
    • 1970-01-01
    相关资源
    最近更新 更多