我编写了这个小程序来对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中存在这个问题,那就太好了。
发布于 2017-07-20 08:46:42
List.subList的API文档说:
如果支持列表(即此列表)在结构上被修改,而不是通过返回的列表,则此方法返回的列表的语义将变得不明确。(结构修改是那些改变列表大小的修改,或者是以这样一种方式干扰它的,即正在进行的迭代可能产生不正确的结果)。
排序确实会改变列表,导致正在进行的迭代会导致不正确的结果。API文档说,在这种情况下所发生的事情是未定义的--实际上这意味着抛出一个ConcurrentModificationException (至少在使用Java8时是这样),正如您的代码所演示的那样。
发布于 2017-07-20 08:49:44
List.sublist返回部分列表的视图,因此不能修改原始列表。如果希望它工作,则需要将子列表重写为新的list对象:
List<Double> l1 = new ArrayList<>(Arrays.asList(2.0, 0.0, 1.0));
List<Double> l2 = new ArrayList<>(l1.subList(0, 3));
Collections.sort(l1);
System.out.println(l2.get(0));否则,l2 vaues将在排序操作之后更改,这将是不需要的,而java不允许它。
https://stackoverflow.com/questions/45209540
复制相似问题