为了避免并发线程修改异常,我使用了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秒)
这个概念对我来说一直模糊不清。任何详细的解释都会非常值得注意。
答案 0 :(得分:2)
问题是Collections.sort()通过获取List的ListIterator进行排序而在幕后工作。然后它使用迭代器的set()方法进行修改,正如Javadoc指出的那样,COWIterators不支持修改操作。
为什么不强制CopyOnWriteArrayList实现自己的排序方法?正如约书亚布洛赫在this interesting conversation中提到的关于排序这些列表的问题,&#34;它违反了兼容性以将方法添加到广泛实现的接口,例如List,所以这不可能。&#34;此外,CopyOnWriteArrayLists&#39;迭代器不允许对基础列表(IMHO)进行修改,因为这些列表上的修改非常昂贵。将它们作为一种重要的修改要求应该始终是一个仔细预谋的决定,(不幸的是)似乎没有本地支持。