Java中的CopyOnWriteArrayList
CopyOnWriteArrayList类 是JDK 1.5中引入的,它实现了 List接口 。它是 ArrayList 的增强版本,在其中所有修改(添加,设置,删除等)都通过创建一个新副本实现。它位于 java.util.concurrent 包中。它是在并发环境中使用的数据结构。
这里有关于CopyOnWriteArrayList的几点说明:
- 正如名称所示,每次更新操作都会创建基础ArrayList的克隆副本,需要在某一点上将两者自动同步,由JVM处理。因此,执行读操作的线程不会受到影响。
- 使用成本很高,因为每次更新操作都会创建一个克隆副本。因此,如果我们的频繁操作是读取操作,则CopyOnWriteArrayList是最佳选择。
- 下划线数据结构是可增长的数组。
- 它是ArrayList的线程安全版本。
- 插入被保留,允许重复,空值和异构对象。
- 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<?extends E> c) | 将指定集合中的所有元素以指定集体的迭代器返回的顺序附加到此列表的末尾。 |
addAll(int index,Collection<?extends E> c) | 将指定集合中的所有元素从指定位置开始插入到此列表中。 |
addAllAbsent(Collection<?extends E> c) | 将指定集合中尚未包含在此列表中的所有元素以指定集合的迭代器返回的顺序附加到此列表的末尾。 |
addIfAbsent(E e) | 添加元素(如果不存在)。 |
clear() | 从列表中删除所有元素。 |
clone() | 返回此列表的浅层副本。 |
contains(Object o) | 如果此列表包含指定的元素,则返回true。 |
containsAll(Collection<?> c) | 如果此列表包含指定集合的所有元素,则返回true。 |
equals(Object o) | 将指定对象与此列表进行比较以判断它们是否相等。 |
forEach(Consumer<?super E> 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(intindex) | 返回此列表中元素的列表迭代器(按正确顺序),从列表中的指定位置开始。 |
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() | 在此列表的元素上创建一个late,并允许一些元素(按正确顺序)进行分区或处理,可以并行执行或顺序执行以便有效地执行大型遍历或映射操作。 subList(int fromIndex,int toIndex) | 返回此列表中指定的fromIndex(包括)和toIndex(不包括)之间的部分视图。 toArray() | 返回包含此列表中所有元素的数组。 toArray(T[] a) | 返回包含此列表中所有元素的数组;返回的数组的运行时类型是指定数组的运行时类型。 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) | 返回此列表中从fromIndex(含)到toIndex(不含)的部分的视图。 |
toArray() | 以正确的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组。 |
toArray(T[] a) | 以正确的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的类型。 |
toString() | 返回此列表的字符串表示形式。 |
从java.util.Collection接口继承的方法:
方法 | 描述 |
---|---|
parallelStream() | 返回一个可能并行的Stream,使用此集合作为其源。 |
stream() | 返回一个顺序Stream,使用此集合作为其源。 |
注意: 在并发环境中,如果希望使用类似于ArrayList的数据结构,则应使用 CopyOnWriteArrayList 。