我想排序CopyOnWriteArrayList。但是当我尝试运行以下代码时
它在扔unsorted operation exception。
public class CopyOnWriteArrayListExample { public static void main(final String[] args) { List<String> list = new CopyOnWriteArrayList<>(); list.add("3"); list.add("2"); list.add("1"); Collections.sort(list); } } Exception in thread "main" java.lang.UnsupportedOperationException at java.util.concurrent.CopyOnWriteArrayList$COWIterator.set(CopyOnWriteArrayList.java:1049) at java.util.Collections.sort(Collections.java:159) at com.sac.list.CopyOnWriteArrayListExample.main(CopyOnWriteArrayListExample.java:15)
提前致谢。
Collections.sort使用ListIterator.set ... for (int j=0; j<a.length; j++) { i.next(); i.set((T)a[j]); }
但是CopyOnWriteArrayList的ListIterator不支持remove,set或add方法。
解决方法:
Object[] a = list.toArray(); Arrays.sort(a); for (int i = 0; i < a.length; i++) { list.set(i, (String) a[i]); }
叶夫根尼(Evgeniy)的解决方案指向正确,但list.set(i, (String) a[i])必须锁定list列表中的每个元素。如果有写入的并发线程list将大大降低循环速度。
list.set(i, (String) a[i])
为了最大程度地减少阻塞,最好减少更改的语句数list:
list
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>(); // ... fill list with values ... ArrayList<Integer> temp = new ArrayList<>(); temp.addAll(list); Collections.sort(temp); list.clear(); // 1st time list is locked list.addAll(temp); // 2nd time list is locked
不利之处在于,如果并发线程list在两者之间进行读取,clear()并且addAll(temp)使用Evgeniy的解决方案,它将看到一个空列表,那么它可能会看到部分排序的列表。
clear()