How to sort CopyOnWriteArrayList
Collections.sort uses ListIterator.set
...
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
but CopyOnWriteArrayList's ListIterator does not support the remove, set or add methods.
Workaround:
Object[] a = list.toArray();
Arrays.sort(a);
for (int i = 0; i < a.length; i++) {
list.set(i, (String) a[i]);
}
Evgeniy's solution points in the right way, but list.set(i, (String) a[i])
has to gain the lock on list
for each element in the list. If there is a concurrent thread which writes into list
this will slow down the loop dramatically.
To minimize blocking it's better to reduce the number of statements which alter 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
The downside is that if a concurrent thread reads list
between clear()
and addAll(temp)
it will see an empty list wheras with Evgeniy's solution it may see a partially sorted list.
In JDK1.8 can use sort(Comparator<? super E> c)
directly.
List<Integer> list = new CopyOnWriteArrayList<Integer>();
list.add(3);
list.add(4);
list.add(1);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});