当前位置: 首页 > 面试题库 >

为什么Collections.sort(List)在带有CopyOnWriteArrayList的Java 8中起作用,而在Java 7中却不起作用?

师曦
2023-03-14
问题内容

我可以使用以下代码和Java 8对用户列表进行排序,而不会出现任何问题:

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

现在,我改用Java 7,但在Eclipse上没有看到错误。但是现在,在Java 7下运行时出现此错误:

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工作方式有所不同(Holger指出,版本8032636)。

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

此实现将指定的列表转储到数组中,对数组进行排序,然后遍历列表,从数组中的相应位置重置每个元素。这样可以避免由于尝试对链表进行适当排序而导致的n²log(n)性能。

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

返回的迭代器在构造迭代器时提供列表状态的快照。在遍历迭代器时不需要同步。 该迭代器不支持removesetadd方法

这说明了使用Java
7运行代码时遇到的错误。作为解决方法,您可以参考此问题,答案是将列表的内容转储到数组中,对数组进行排序并将元素放回清单。

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

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

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



 类似资料:
  • 我正在学习代码通过yt黑客客户端,但我有问题理解一些东西,。https://www.youtube.com/watch?v=-vh8wuja1re&t=171s大约2到3分钟,他将公共静态void启动放到一个他命名为“client”类中。然后他上了Minecraft的课,在某一行上了Client.Startup。我想知道为什么这会起作用,因为这两个类都不是主要的类,我尝试在一个不同的正常Java

  • 通过选择,,和,我创建了一个全新的Spring初始化项目。 我做了一个小项目: 我试着将三个人保存到数据库中。保存方法只返回需要执行的Mono。如果我尝试通过简单的订阅来执行它,一切都很好: 但是,当我使用而不是时,应用程序挂起: 如果我手动查询数据库,我会看到Jim已被保存,但Jack和John未被保存。 这是窃听器,还是我做错了什么?我希望在代码进一步发展之前保证用户在数据库中,所以我真的很想

  • 问题内容: 显然有一些根本尚不了解的东西。 我试图使用户成为Angular Ui.Bootstrap中的Modal模块的用户,但是我发现我的点击没有激活该功能- 因此将其简化为一个非常简单的测试用例,如下所示,当ng-click时我看不到任何调用指向一个函数(alert或console.log),但是当ng- click指向一个仅表示表达式的东西时确实起作用 为什么在第一个示例中未调用? http

  • 问题内容: 为什么这项工作有效- 但这不是- 第二种情况下的输出为。你能解释一下输出吗? 问题答案: 该方法没有返回值。它会在适当的位置更改列表,并且由于您没有将分配给任何变量,因此只是“迷失在空间” 我没有重载所有有问题的方法,但是概念应该很清楚。

  • 我试图在我的Word文档中使用块,但我有一些问题。首先,当我在我的文档中声明一个块时,如果我不使用函数“cloneBlock”,结果会出现这样的情况: 也许我必须使用那个函数才能正常出现。但是我的主要问题是“删除块”不起作用。如果我不克隆块,生成的docx就会损坏。但是如果我克隆了这个块,函数“删除块”不会删除这个块,它会在我的最终docx文件中显示那个块内的信息。 这是我的代码: Docx模板:

  • 问题内容: 我的Dockerfile创建一个目录,将其chown,然后再列出该目录。该目录仍归root用户所有。这是为什么? 这是Dockerfile: 这是“ docker build”的输出: Docker版本1.2.0,构建fa7b24f 主机运行Ubuntu 12.04,但具有3.13.0-36通用内核。 问题答案: 回答我自己的问题:它声明为卷。如果取出VOLUME指令,则将生效。 此外