当前位置: 首页 > 知识库问答 >
问题:

在CopyOnArrayList上执行排序操作会产生java。lang.UnsupportedOperationException

公冶元青
2023-03-14

为了避免并发线程修改异常,我使用了CopyOnArrayList

异常在线程"main"java.lang.不支持操作异常

因此,我尝试读取可用于CopyOnArrayList的javadoc

上面说

不支持迭代器本身的元素更改操作(删除、设置和添加)。这些方法会抛出不支持的操作异常。

但据我所知,排序在任何意义上都需要在临时列表中添加和删除元素。但它为什么不这么做呢。它适用于对象克隆,所以这个因素会以任何方式影响。

测试代码:

package test;

import java.util.Comparator;

/**
 *
 * @author vaibhav.kashyap
 */
public class Student implements Comparator<Student>{

    private String name = "";
    private int age = -1;

    public Student(){

    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int compare(Student o1, Student o2) {
        return o1.getAge() <o2.getAge() ?-1:o1.getAge()==o2.getAge()?0:1;
    }

}

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * @author vaibhav.kashyap
 */
public class Main {
    List<Student> stuList = new CopyOnWriteArrayList<Student>();
    public static void main(String ar[]){
        List<Student> tempList = new Main().makeList();

        Collections.sort(tempList, new Student());

        for(Student s : tempList){
            System.out.println(s.getAge());
        }
    }

    public List<Student> makeList(){
        Student stu = null;
        Scanner sc = new Scanner(System.in);


        for(int i=0 ; i<5; i++){
         stu = new Student();
         System.out.println("Enter name");
         String name = sc.next();
         stu.setName(name);
         System.out.println("Enter age");
         int age = sc.nextInt();
         stu.setAge(age);
         stuList.add(stu);
        }

        return stuList;
    }
}

输出:运行:输入姓名a输入年龄12输入姓名b输入年龄10输入姓名c输入年龄05输入姓名d输入年龄100输入姓名e输入年龄01线程“主”中的异常java.lang.不支持操作异常java.util.concurrent.CopyOnWriteArrayList$COWIterator.set(CopyOnWriteArrayList.java:1049)java.util.Collections.sort(Collections.java:221)测试。Main.main(Main.java:23)Java结果: 1构建成功(总时间: 30秒)

这个概念对我来说一直是模糊的,任何详细的解释都会有很高的可欣赏性。

共有1个答案

卫彭亮
2023-03-14

问题是,Collections.sort()在幕后为要排序的List获取一个ListIterator,然后使用迭代器的set()方法进行修改,正如Javadoc所指出的,COWIterator不支持修改操作。

为什么不强制CopyOnWriteArrayList实现自己的排序方法呢?正如Joshua Bloch在这篇关于列表排序问题的有趣对话中所说,“在广泛实现的接口(如List)中添加方法违反了兼容性,所以这是不可能的。”此外,CopyonWriteArrayList的迭代器不允许对基础列表(IMHO)进行修改,因为对这些列表的修改非常昂贵。根据排序要求对它们进行大量修改应该始终是一个经过精心策划的决定,不幸的是,这似乎没有得到本机的支持。

 类似资料:
  • 问题内容: 我有一个表:abc_test,列为n_num,k_str。 此查询不起作用: 但这是可行的: DISTINCT和ORDER BY关键字在内部如何工作以使两个查询的输出都被更改? 问题答案: 据我从你的问题上的理解。 与众不同:-表示选择与众不同(所有选择的值都应该是唯一的)。order By:-仅表示按照您的要求对选定的行进行排序。 您的第一个查询中的问题是例如:我有一张桌子 现在查询

  • 因为在过滤2之后,我们还得再找到一个元素来分层极限(2),操作,那么为什么输出不像我解释的那样呢?

  • 无法在下面的链接中执行右键单击操作。我们尝试了几乎所有的案例来实现自动化。https://the-internet.herokuapp.com/context_menu 我使用的是Selenium 3.3和geckodrivers的最新版本。 动作动作=新动作(驱动);行为moveToElement(元素)。点击();行为上下文单击(元素)。build()。执行();行为发送键(键。箭头向下)。发

  • 我有一个带有Vaadin集成(v14)的Spring Boot项目。我希望我的应用程序做一些后台操作,并在基于Vaadin的前端上表示结果。为此,我有一个视图,它是用Vaadin Designer(.js)生成的聚合物模板,并连接到Java companion类。在这个视图中,我只是简单地添加了一个用以下监听器初始化的按钮: 我正试图访问文档中所说的UI。然而,当它被执行时,它只到达第一个“等待”

  • 我正在使用一个无线电组件,当选择一个项目时,我想在该组件上执行对支持bean的操作(不是导航到结果页面,而是执行一些操作,然后通过Ajax更新当前页面)。问题是我无法让支持bean值更改侦听器操作执行 还有背豆法... 代码中是否有我遗漏的错误?我使用了相同的结构来选择多个复选框,这是有效的。。。

  • 我正在尝试连接到我自己的一个新的Minecraft服务器(从我自己的客户机)。这是一个全新的Ubuntu18.04安装Java10和最新的Minecraft 1.12服务器。