对CopyOnArrayList执行排序操作会导致java.lang.UnsupportedOperationException

时间:2014-11-12 06:28:32

标签: java sorting collections comparator copyonwritearraylist

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

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

结果我尝试阅读CopyOnArrayList

的javadoc

  

迭代器本身的元素更改操作(删除,设置和   add)不受支持。抛出这些方法   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;
    }
}

输出: 跑: 输入名字 一个 输入年龄 12 输入名字 b 输入年龄 10 输入名字 C 输入年龄 05 输入名字 d 输入年龄 100 输入名字 Ë 输入年龄 01 线程“main”java.lang.UnsupportedOperationException中的异常     at java.util.concurrent.CopyOnWriteArrayList $ COWIterator.set(CopyOnWriteArrayList.java:1049)     在java.util.Collections.sort(Collections.java:221)     在test.Main.main(Main.java:23) Java结果:1 建立成功(总时间:30秒)

这个概念对我来说一直模糊不清。任何详细的解释都会非常值得注意。

1 个答案:

答案 0 :(得分:2)

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

为什么不强制CopyOnWriteArrayList实现自己的排序方法?正如约书亚布洛赫在this interesting conversation中提到的关于排序这些列表的问题,&#34;它违反了兼容性以将方法添加到广泛实现的接口,例如List,所以这不可能。&#34;此外,CopyOnWriteArrayLists&#39;迭代器不允许对基础列表(IMHO)进行修改,因为这些列表上的修改非常昂贵。将它们作为一种重要的修改要求应该始终是一个仔细预谋的决定,(不幸的是)似乎没有本地支持。