排序的ConcurrentModification异常

时间:2017-07-20 08:36:26

标签: java concurrentmodification

我写了这个小程序来排序arrays。根据我的理解,它应该打印0,1,2

然而,当我运行此程序时,我得到ConcurrentModificationException

    public class Test {
    public static void main(String[] args) {
    List<Double> l1 = new ArrayList<Double>(Arrays.asList(2., 0., 1.));
    List<Double> l2 = l1.subList(0, 3);
    Collections.sort(l1);
    System.out.println(l2.get(0));
    }
}

我真的不确定此异常的根本原因。

有人可以帮我理解我犯错的地方吗?

注意:这个问题在JAVA 7上不存在,如果有人在JAVA 8中告诉它为什么而在JAVA 7中没有,那将会很棒

2 个答案:

答案 0 :(得分:7)

List.subList的API文档说:

  

如果支持列表(即此列表)在结构上以除返回列表之外的任何方式进行修改,则此方法返回的列表的语义将变为未定义。 (结构修改是那些改变了这个列表大小的修改,或者以这样的方式扰乱它,即正在进行的迭代可能会产生不正确的结果。)

排序确实会改变列表,使得正在进行的迭代会导致错误的结果。 API文档说明在这种情况下发生的事情是未定义的 - 实际上这意味着抛出ConcurrentModificationException(至少在使用Java 8时),正如您的代码所示。

答案 1 :(得分:0)

List.sublist返回列表的一部分视图,因此您无法修改原始列表。如果您希望它工作,那么您需要将子列表重写为新的列表对象:

settings->build->gradle->experimental

否则l2 vaues会在排序操作后发生变化,这是不必要的,而java也不允许这样做。