为什么Collections.sort(List)在Java 8中使用CopyOnWriteArrayList但在Java 7中不起作用? [英] Why does Collections.sort(List) work in Java 8 with CopyOnWriteArrayList but not in Java 7?

查看:375
本文介绍了为什么Collections.sort(List)在Java 8中使用CopyOnWriteArrayList但在Java 7中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用以下代码和Java 8对用户列表进行排序而没有任何问题:

I can sort a list of users without any problems using the following code and Java 8:

CopyOnWriteArrayList<User> allCurrentLoginnedUsersList = new CopyOnWriteArrayList<>(); 
Collections.sort(allCurrentLoginnedUsersList);

现在,我改为Java 7,我在eclipse上看到没有错误。但现在,当在Java 7下运行时,我遇到了这个错误:

Now, I changed to Java 7 and I saw no errors on eclipse. But now, when running under Java 7 I got this error:

java.lang.UnsupportedOperationException
    at java.util.concurrent.CopyOnWriteArrayList$COWIterator.set(CopyOnWriteArrayList.java:1049)
    at java.util.Collections.sort(Collections.java:221)
    at com.fluent.User.sortAllCurrentLoginnedUsers(User.java:446)

如何解决?

推荐答案

Java 7(和早期版本的Java 8)和Java 8u20之间的方式发生了变化 Collections.sort 工作( issue 8032636 ,如Holger )。

There was a change between Java 7 (and early version of Java 8) and Java 8u20 in the way Collections.sort work (issue 8032636, as noted by Holger).

Java 7 Collections.sort(list,c) 指定:

Java 7 Collections.sort(list, c) specifies that:


此实现将指定的列表转储到数组中,对数组进行排序,并迭代列表重置每个元素数组中的对应位置。这样可以避免因尝试对链接列表进行排序而导致的n²log(n)性能。

This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n² log(n) performance that would result from attempting to sort a linked list in place.

查看代码,这是通过从列表中获取 ListIterator 来完成的。但是, CopyOnWriteArrayList listIterator() 方法声明返回的迭代器不支持 set operation:

Looking at the code, this is done by obtaining a ListIterator from the list. However, CopyOnWriteArrayList listIterator() method states that the iterator returned does not support the set operation:


返回的迭代器提供了构造迭代器时列表状态的快照。遍历迭代器时不需要同步。 迭代器不支持删除设置添加方法

The returned iterator provides a snapshot of the state of the list when the iterator was constructed. No synchronization is needed while traversing the iterator. The iterator does NOT support the remove, set or add methods.

这解释了使用Java 7运行代码时出现的错误。作为解决方法,您可以参考这个问题,其答案是将列表内容转储到数组中,对数组进行排序和将元素放回列表中。

This explains the error you are getting when running your code with Java 7. As a workaround, you can refer to this question where the answer is to dump the content of the list into an array, sort the array and put the elements back in the list.

在Java 8中, Collections.sort (list,c) 更改实现:

In Java 8, Collections.sort(list, c) changed implementation:


此实现遵循 List.sort(Comparator)使用指定列表和比较器的方法。

This implementation defers to the List.sort(Comparator) method using the specified list and comparator.

新方法 CopyOnWriteArrayList.sort(c) (在Java 8中引入)不使用列表迭代器,所以它可以正常工作。

And the new method CopyOnWriteArrayList.sort(c) (introduced in Java 8) does not use the list iterator so it works correctly.

这篇关于为什么Collections.sort(List)在Java 8中使用CopyOnWriteArrayList但在Java 7中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆