我想对CopyOnWriteArrayList
进行排序。但是下面的代码抛出了一个UnsupportedOperationException
:
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);
}
}
个字符
如何对CopyOnWriteArrayList
进行排序?
5条答案
按热度按时间9jyewag01#
sort使用ListIterator.set
字符串
但CopyOnWriteArrayList的ListIterator不支持remove、set或add方法。
解决方法:
型
pnwntuvh2#
Evgeniy的解决方案是正确的,但是
list.set(i, (String) a[i])
必须为列表中的每个元素获得list
上的锁。如果有一个并发线程写入list
,这将大大降低循环速度。为了减少阻塞,最好减少改变
list
的语句的数量:字符串
缺点是,如果一个并发线程在
clear()
和addAll(temp)
之间读取list
,它将看到一个空列表,而Evgeniy的解决方案可能会看到一个部分排序的列表。zbwhf8kr3#
在JDK1.8中可以直接使用
sort(Comparator<? super E> c)
。字符串
zynd9foi4#
因为CopyOnWriteArrayList在每次你修改它的时候都会复制它自己,它的Iterator不允许你修改列表。如果它允许,Iterator就不是线程安全的,而线程安全是这个类的全部意义。
Collections.sort()
将不工作,因为它需要一个支持set()
方法的Iterator。6ioyuze25#
从Java 8开始,给定的代码无一例外地工作。
在Java 8之前的版本中,
Collections.sort
在给定列表的ListIterator
上使用ListIterator.set
,转发该方法抛出的任何UnsupportedOperationException
。CopyOnWriteArrayList
不支持对迭代器本身(
remove
、set
和add
)的元素更改操作。这些方法抛出UnsupportedOperationException
。从Java 8开始,
Collections.sort
委托给新添加的List.sort
方法。CopyOnWriteArrayList
使用与之一起工作的自定义实现重写此方法。因此,Java 8版本的Collections.sort
成功地对列表进行排序,而不是像Java的早期版本那样抛出异常。Collections.sort
实施说明:
此实现遵循
List.sort(Comparator)
方法,使用指定的列表和比较器。