Java CopyOnWriteArrayList

Java CopyOnWriteArrayList

CopyOnWriteArrayList类 是在JDK 1.5中引入的,它实现了 List接口。 它是 ArrayList 的一个增强版 ,其中所有的修改(添加、设置、删除等)都是通过制作一个新的副本来实现的。它可以在 java.util.concurrent 包中找到。它是一个为在并发环境中使用而创建的数据结构。

Java中的CopyOnWriteArrayList

下面是关于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 **, **Collection **, List, **RandomAccess 接口。

构造函数

1.CopyOnWriteArrayList() : 创建一个空列表。

CopyOnWriteArrayList c = new CopyOnWriteArrayList();
Java

2.CopyOnWriteArrayList(Collection obj) : 创建一个包含指定集合元素的列表,其顺序是由集合的迭代器返回。

CopyOnWriteArrayList c = new CopyOnWriteArrayList(Collection obj);
Java

3.CopyOnWriteArrayList(Object[] obj); : 创建一个持有给定数组副本的列表。

CopyOnWriteArrayList c = new CopyOnWriteArrayList(Object[] obj);
Java

例子

// Java program to illustrate
// CopyOnWriteArrayList class
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
 
public class ConcurrentDemo extends Thread {
 
    static CopyOnWriteArrayList<String> l
        = new CopyOnWriteArrayList<String>();
 
    public void run()
    {
        // Child thread trying to
        // add new element in the
        // Collection object
        l.add("D");
    }
 
    public static void main(String[] args)
        throws InterruptedException
    {
        l.add("A");
        l.add("B");
        l.add("c");
 
        // We create a child thread
        // that is going to modify
        // ArrayList l.
        ConcurrentDemo t = new ConcurrentDemo();
        t.run();
 
        Thread.sleep(1000);
 
        // Now we iterate through
        // the ArrayList and get
        // exception.
        Iterator itr = l.iterator();
        while (itr.hasNext()) {
            String s = (String)itr.next();
            System.out.println(s);
            Thread.sleep(1000);
        }
        System.out.println(l);
    }
}
Java

输出

A
B
c
D
[A, B, c, D]
Java

迭代 CopyOnWriteArrayList: 我们可以使用iterator()方法迭代CopyOnWriteArrayList。需要注意的是,我们创建的迭代器是原始列表的一个不可改变的快照。因为这个属性,我们可以看到在第一次迭代时, GfG 没有被打印出来。

// Java program to illustrate
// CopyOnWriteArrayList class
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
 
class Demo {
    public static void main(String[] args)
    {
 
        CopyOnWriteArrayList<String> list
            = new CopyOnWriteArrayList<>();
 
        // Initial Iterator
        Iterator itr = list.iterator();
        list.add("GfG");
        System.out.println("List contains: ");
        while (itr.hasNext())
            System.out.println(itr.next());
 
        // iterator after adding an element
        itr = list.iterator();
        System.out.println("List contains:");
        while (itr.hasNext())
            System.out.println(itr.next());
    }
}
Java

输出

List contains: 
List contains:
GfG
Java

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 operator) | 用运算符的结果来替换这个列表中的每个元素。
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

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册