CopyOnWriteArraySet基于CopyOnWriteArrayList实现功能,通过检查元素是否包含在列表中,实现集合的功能。来自JDK10。
public class CopyOnWriteArraySet<E> extends AbstractSet<E> implements java.io.Serializable
由于CopyOnWriteArraySet利用CopyOnWriteArrayList实现功能,所以数据成员中包含了一个CopyOnWriteArrayList实例。
private final CopyOnWriteArrayList<E> al;
初始化空集合
public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList<E>(); }
通过指定集合初始化,集合c为空则抛出NullPointerException
public CopyOnWriteArraySet(Collection<? extends E> c) { if (c.getClass() == CopyOnWriteArraySet.class) { // 集合c是CopyOnWriteArraySet,里面所有元素都是唯一的 @SuppressWarnings("unchecked") CopyOnWriteArraySet<E> cc = (CopyOnWriteArraySet<E>)c; // 直接用集合c构造实例 al = new CopyOnWriteArrayList<E>(cc.al); } else { // 集合c类型不是CopyOnWriteArraySet,不能保证集合c的元素是唯一的 al = new CopyOnWriteArrayList<E>(); // 需通过addAllAbsent()逐个添加元素去重 al.addAllAbsent(c); } }
// 添加指定元素,如果元素已存在,则该元素不会添加 public boolean add(E e) { return al.addIfAbsent(e); // 此元素成功添加返回true,否则返回false } // 把集合c中所有的元素添加到ArraySet实例中 public boolean addAll(Collection<? extends E> c) { return al.addAllAbsent(c) > 0; // 有任何元素添加到 }
// 清空Set中所有元素 public void clear() { al.clear(); } // 移除指定元素 public boolean remove(Object o) { return al.remove(o); } // 移除Set与集合c共有的元素 public boolean removeAll(Collection<?> c) { return al.removeAll(c); }
// 查找指定对象是否包含在那本实例 public boolean contains(Object o) { return al.contains(o); } // 检查Set是否全包含集合c的元素 public boolean containsAll(Collection<?> c) { return (c instanceof Set) ? compareSets(al.getArray(), (Set<?>) c) >= 0 : al.containsAll(c); } // 检查集合是否为空 public boolean isEmpty() { return al.isEmpty(); }
// 仅保留Set与集合c共有的元素 public boolean retainAll(Collection<?> c) { return al.retainAll(c); }
// 返回集合已保存元素的数量 public int size() { return al.size(); } // 通过ArraySet返回一个数组 public Object[] toArray() { return al.toArray(); } public <T> T[] toArray(T[] a) { return al.toArray(a); } // 检查snapshot是否为set的超集: // * -1: snapshot不是set的超集; // * +0: 两个集合包含的元素完全相同; // * +1: snapshot是set的超集,即所有set的元素snapshot都包含; private static int compareSets(Object[] snapshot, Set<?> set) { // Uses O(n^2) algorithm, that is only appropriate for small // sets, which CopyOnWriteArraySets should be. // // Optimize up to O(n) if the two sets share a long common prefix, // as might happen if one set was created as a copy of the other set. final int len = snapshot.length; // Mark matched elements to avoid re-checking final boolean[] matched = new boolean[len]; // j is the largest int with matched[i] true for { i | 0 <= i < j } int j = 0; outer: for (Object x : set) { for (int i = j; i < len; i++) { if (!matched[i] && Objects.equals(x, snapshot[i])) { matched[i] = true; if (i == j) do { j++; } while (j < len && matched[j]); continue outer; } } return -1; } return (j == len) ? 0 : 1; } // 返回迭代器,遍历的集合是一份快照,且不支持remove()操作 public Iterator<E> iterator() { return al.iterator(); } // 检查对象o和被实例是否为同一个对象,或其中包含的元素完全相同 public boolean equals(Object o) { return (o == this) || ((o instanceof Set) && compareSets(al.getArray(), (Set<?>) o) == 0); }
public Spliterator<E> spliterator() { return Spliterators.spliterator (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT); }
上一篇
Java源码系列(14) -- CopyOnWriteArrayList