【问题标题】:ConcurrentModificationException? [duplicate]并发修改异常? [复制]
【发布时间】:2013-03-16 01:01:52
【问题描述】:

我正在尝试按开始时间排序时间跨度列表(表示为具有开始时间和结束时间的 Time[] 数组)。我正在尝试使用以下嵌套循环来执行此操作:

            for (Time[] span : workingList){
            Time[] compareTo = workingList.get(0);

                for (Time[] inSpan : workingList){
                    if (inSpan[0].before(compareTo[0])){
                    compareTo = inSpan;
                    }
                }
            workingList.remove(compareTo);
            toReturn.add(compareTo);
        }

    }

但它在for (Time[] span : workingList) 行(最上面的那个)上抛出了一个java.util.ConcurrentModificationException。我以前从未见过这个异常,有人可以向我解释它的含义和原因。

我也愿意为此提供更好的算法建议。

【问题讨论】:

  • 供将来参考:当您对异常有疑问时,您可以随时查阅文档。如果您在 Google 上搜索“Java 7 ConcurrentModificationException”,第一个结果会将您带到文档。如果您阅读该页面顶部的概述,它会解释这个确切的场景。

标签: java


【解决方案1】:
workingList.remove(compareTo);

您在迭代集合时正在修改它。

你应该使用类似的东西:

ListIterator<Time[]> it = workingList.listIterator();

while (it.hasNext()) {
  Time[] time = it.next();
  ..
  it.remove();
}

也有不使用列表迭代器的方法,但这似乎更正确。

【讨论】:

  • 另一种选择是构建您要在 WHILE 迭代中删除的项目列表,并在 AFTER 迭代中删除它们。
  • 这主要取决于算法,在 OP 情况下,如果他要删除的元素并不总是与它正在迭代的元素相同,那么构建一个临时列表可能是唯一的选择。
【解决方案2】:

我的建议是您使用Collections.sort() 来订购列表。它为您进行排序,并使您尝试做的事情更具可读性。您需要在调用该方法时指定自己的 Comparator - 例如:

    Collections.sort(workingList,new Comparator<Time[]>() {
        @Override
        public int compare(Time[] time1, Time[] time2) {
            return time1[0].before(time2[0]);
        }
    });

这会将工作列表排序为您的规格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-24
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    相关资源
    最近更新 更多