1

为了避免并发线程修改异常,当我尝试使用帮助 Collection 的类排序方法对该列表进行排序时,我使用了 CopyOnArrayList 及后来导致以下异常:-

线程“主”java.lang.UnsupportedOperationException 中的异常

结果,我尝试阅读可用于CopyOnArrayList的 javadoc

它说

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

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

测试代码:

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 线程“main”中的异常 java.lang.UnsupportedOperationException 在 java.util。 concurrent.CopyOnWriteArrayList$COWIterator.set(CopyOnWriteArrayList.java:1049) at java.util.Collections.sort(Collections.java:221) at test.Main.main(Main.java:23) Java 结果:1 BUILD SUCCESSFUL(总计时间:30秒)

这个概念对我来说一直很模糊。任何详细的解释都将是非常可观的。

4

1 回答 1

2

问题是 Collections.sort() 通过获取 ListIterator 来对要排序的列表在幕后工作。然后它使用该迭代器的 set() 方法进行修改,正如 Javadoc 指出的那样,COWIterators 不支持修改操作。

为什么不强制 CopyOnWriteArrayList 实现自己的排序方法?正如 Joshua Bloch 在关于排序这些列表的问题的有趣对话中所说的那样,“将方法添加到 List 等广泛实现的接口中违反了兼容性,因此这是不可能的。” 此外,不允许 CopyOnWriteArrayLists 的迭代器对底层列表进行修改(恕我直言),因为在这些列表上修改非常昂贵。尽可能多地修改它们应该始终是一个精心策划的决定,(不幸的是)似乎没有原生支持。

于 2014-11-12T07:40:05.617 回答