【问题标题】:ConcurrentModificationException when clearing a sub list [duplicate]清除子列表时出现 ConcurrentModificationException [重复]
【发布时间】:2013-07-27 16:01:18
【问题描述】:

为什么当我在主列表之后清除子列表时,下面的代码会抛出ConcurrentModificationExcrption,但如果我清除子列表然后是主列表,则不会?

ArrayList<Integer> masterList = new ArrayList<Integer>();
List<Integer> subList;

// Add some values to the masterList
for (int i = 0; i < 10; i++) {
    masterList.add(i * i);
}

// Extract a subList from the masterList
subList = masterList.subList(5, masterList.size() - 1);

// The below throws ConcurrentModificationException
masterList.clear();
subList.clear(); // Exception thrown in this line

// The below doesn't throw any exception
subList.clear();
masterList.clear(); // No exception thrown. Confused??

【问题讨论】:

    标签: java list


    【解决方案1】:

    SubList不是一个独立的实体,只是给出原始列表的一个视图,内部引用的是同一个列表。因此,它的设计似乎是,如果底层列表在结构上被修改(添加/删除元素),它就无法履行其合同。

    可以看出here in the source code of SubList,方法checkForComodification检查底层列表是否被修改,因此如果SubListmodCount(列表被结构修改的次数)值不是与父 ArrayList 相同,则抛出 ConcurrentModificationException

    因此,清除创建 SubList 的父 ArrayList 可能会导致 SubList 的某些操作导致 ConcurrentModificationException

    【讨论】:

    • 这是非常有用的。谢谢。
    【解决方案2】:

    subListmasterList 的视图。只有 1 个基础集合。现在 masterList 是一种superset 的子列表。所以,

    • 如果masterlist's 元素被移除,sublist 将不存在 //异常情况
    • 如果 sublist's 元素被移除,masterlist 可以存在 //OK

    【讨论】:

    • 是不是 subList 引用 masterList 的元素,当我执行 masterList.clear() 时,引用被破坏并且 subList.clear() 抛出异常?
    【解决方案3】:

    根据ArrayList docsubList()返回一个由原始ArrayList支持的子列表,因此如果原始更改子列表也会发生变化,当您执行subList.clear()时,子列表本身不再存在。

    【讨论】:

      【解决方案4】:

      来自the API docs

      如果后备列表(即此列表)以除通过返回列表之外的任何方式结构修改,则此方法返回的列表的语义将变为未定义。 (结构性修改是改变这个列表的大小,或者以其他方式扰乱它,使得正在进行的迭代可能产生不正确的结果。)

      未定义的语义当然意味着允许抛出异常(实际上这可能是最明智的做法)。

      因此您可以更改子列表的大小并将这些更改反映在主列表中,但反之则不然。

      【讨论】:

        猜你喜欢
        • 2018-01-09
        • 2021-12-15
        • 1970-01-01
        • 1970-01-01
        • 2013-12-14
        • 1970-01-01
        • 2013-07-15
        • 2020-11-22
        • 2020-11-17
        相关资源
        最近更新 更多