Java CopyOnWriteArrayList
CopyOnWriteArrayList类 是在JDK 1.5中引入的,它实现了 List接口。 它是 ArrayList 的一个增强版 ,其中所有的修改(添加、设置、删除等)都是通过制作一个新的副本来实现的。它可以在 java.util.concurrent 包中找到。它是一个为在并发环境中使用而创建的数据结构。
下面是关于CopyOnWriteArrayList的几个要点
- 顾名思义,CopyOnWriteArrayList创建了一个ArrayList底层的克隆副本,对于每一个更新操作,在某一点上两者都会自动同步,这一点由JVM来负责。因此,对于正在进行读操作的线程没有影响。
- 它的使用成本很高,因为每次更新操作都会创建一个克隆的副本。因此,如果我们经常进行读取操作,CopyOnWriteArrayList是最佳选择。
- 下划线的数据结构是一个可增长的数组。
- 它是ArrayList的一个线程安全版本。
- 插入被保留,重复的、空的和异质的对象被允许。
- 关于CopyOnWriteArrayList最重要的一点是CopyOnWriteArrayList的迭代器不能执行移除操作,否则我们会得到运行时异常 UnsupportedOperationException 。 CopyOnWriteArrayList迭代器上的add()和set()方法也会抛出 UnsupportedOperationException。 同时CopyOnWriteArrayList的迭代器也不会抛出 ConcurrentModificationException。
声明
public class CopyOnWriteArrayList<E> extends Object implements List<E>, RandomAccess, Cloneable, Serializable
这里,E是这个集合中持有的元素的类型。
注意: 该类实现了 Serializable , Cloneable , Iterable
构造函数
1.CopyOnWriteArrayList() : 创建一个空列表。
2.CopyOnWriteArrayList(Collection obj) : 创建一个包含指定集合元素的列表,其顺序是由集合的迭代器返回。
3.CopyOnWriteArrayList(Object[] obj); : 创建一个持有给定数组副本的列表。
例子
输出
迭代 CopyOnWriteArrayList: 我们可以使用iterator()方法迭代CopyOnWriteArrayList。需要注意的是,我们创建的迭代器是原始列表的一个不可改变的快照。因为这个属性,我们可以看到在第一次迭代时, GfG 没有被打印出来。
输出
CopyOnWriteArrayList的方法 。
方法 | 描述 |
---|---|
add(E e) | 将指定的元素添加到这个列表的末尾。 |
add(int index, E element) | 在这个列表中的指定位置插入指定的元素。 |
addAll(Collection c) | 按照指定集合的迭代器返回的顺序,将指定集合中的所有元素追加到这个列表的末尾。 addAll(int index, Collection c) | 将指定集合中的所有元素插入到这个列表中,从指定位置开始。 addAllAbsent(Collection c) | 将指定集合中尚未包含在此列表中的所有元素,按照指定集合的迭代器返回的顺序,追加到此列表的末尾。 addIfAbsent(E e) | 如果不存在,则添加该元素。 clear() | 移除这个列表中的所有元素。 clone() | 返回此列表的浅层副本。 contains(Object o) | 如果这个列表包含指定的元素,则返回 true。 containsAll(Collection c) |
如果这个列表包含指定集合的所有元素,则返回 true。 |
equals(Object o) | 将指定的对象与这个列表进行比较,看是否相等。 |
forEach(Consumer action) | 对Iterable中的每个元素执行给定的动作,直到所有元素都被处理完或者该动作抛出一个异常。 get(int index) | 返回该列表中指定位置的元素。 hashCode() | 返回此列表的哈希代码值。 indexOf(E e, int index) | 返回指定元素在此列表中第一次出现的索引,从索引开始向前搜索,如果没有找到该元素则返回-1。 indexOf(Object o) | 返回指定元素在此列表中第一次出现的索引,如果此列表不包含该元素则返回-1。 isEmpty() | 如果这个列表不包含任何元素,则返回 true。 iterator() | 以适当的顺序返回这个列表中的元素的迭代器。 lastIndexOf(E e, int index) | 返回指定元素在此列表中最后出现的索引,从索引开始向后搜索,如果没有找到该元素则返回-1。 lastIndexOf(Object o) | 返回指定元素在此列表中最后出现的索引,如果此列表不包含该元素则返回-1。 listIterator() | 返回列表中元素的迭代器(按正确顺序)。 listIterator(int index) | 返回一个列表中元素的迭代器(按照适当的顺序),从列表中的指定位置开始。 remove(int index) | 移除这个列表中指定位置的元素。 remove(Object o) | 移除这个列表中第一次出现的指定元素,如果它存在的话。 removeAll(Collection c) |
从这个列表中移除所有包含在指定集合中的元素。 |
removeIf(Predicate filter) | 移除这个集合中满足给定谓词的所有元素。 replaceAll(UnaryOperator retainAll(Collection c) |
只保留这个列表中包含在指定集合中的元素。 |
set(int index, E element) | 用指定的元素替换这个列表中指定位置上的元素。 |
size() | 返回此列表中的元素数量。 |
sort(Comparator<? super E> c) | 按照指定的比较器所引起的顺序对这个列表进行排序。 |
spliterator() | 返回列表中的元素的Spliterator。 |
subList(int fromIndex, int toIndex) | 返回列表中从Index(包括)到toIndex(不包括)之间部分的视图。 |
toArray() | 返回一个包含此列表中所有元素的数组,并以适当的顺序(从第一个到最后一个元素)排列。 |
toArray(T[] a) | 返回一个数组,包含这个列表中的所有元素,并以适当的顺序排列(从第一个元素到最后一个元素);返回的数组的运行时类型是指定数组的类型。 |
toString() | 返回此列表的字符串表示。 |
从java.util.Collection界面继承的方法
方法 | 描述 |
---|---|
parallelStream() | 返回一个以该集合为源的可能的并行流。 |
stream() | 返回一个以该集合为源的顺序流。 |
注意: 当我们喜欢在并发环境中使用类似于ArrayList的数据结构时,我们应该使用 CopyOnWriteArrayList 。