CopyOnWriteArraySet源码分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CopyOnWriteArraySet源码分析相关的知识,希望对你有一定的参考价值。
分析完CopyOnWriteArrayList之后接着看CopyOnWriteArraySet。CopyOnWriteArraySet与CopyOnWriteArrayList相比不同之处就是不能添加重复的元素,Set集合没有按索引直接获取或修改或添加或删除的方法(get(int index),add(int index,E e),set(int index,E e),remove(int index))。
CopyOnArraySet类结构如下:
public class CopyOnWriteArraySet<E> extends AbstractSet<E> implements java.io.Serializable;AbstractSet是set接口的骨干实现,从而最大限度的减少了实现此接口所需的工作。
1、对于CopyOnWriteArraySet需要掌握以下几点:
·构造方法:CopyOnWriteArraySet();
·添加元素:即add(E)方法;
·删除对象:即remove(E)方法;
·遍历所有对象:即iterator(),在实际中更常用的是增强型的for循环去做遍历。
以上操作底层都是对CopyOnWriteArrayList操作,分析过CopyOnWriteArrayList,这些方法就比较简单了。
2、构造方法:
/**
- 创建一个空的set
*/
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>(); //底层转化为了对CopyOnWriteArrayList的操作
}
/**
- Creates a set containing all of the elements of the specified
- collection. 使用指定的元素创建set
- @param c the collection of elements to initially contain
- @throws NullPointerException if the specified collection is null
*/
public CopyOnWriteArraySet(Collection<? extends E> c) {
al = new CopyOnWriteArrayList<E>();
al.addAllAbsent(c); //元素不存在时添加
}
3、添加元素 - @param e element to be added to this set
- @return <tt>true</tt> if this set did not already contain the specified
-
element
*/
public boolean add(E e) {
return al.addIfAbsent(e);//元素不存在时添加
}/**
- Append the element if not present.如果元素不存在,则追加元素
- @param e element to be added to this list, if absent
- @return <tt>true</tt> if the element was added
*/
public boolean addIfAbsent(E e) {
final ReentrantLock lock = this.lock;
lock.lock(); //尝试申请独占锁
try {
// Copy while checking if already present. 复制数组,同时检查元素是否存在
// This wins in the most common case where it is not present
Object[] elements = getArray();//获取当前数组
int len = elements.length;
Object[] newElements = new Object[len + 1];
for (int i = 0; i < len; ++i) {
if (eq(e, elements[i]))
return false; // exit, throwing away copy 退出判断,并扔掉副本
else
newElements[i] = elements[i]; //当前元素不存在,则直接拷贝
}
newElements[len] = e; //遍历完整个数组,还是不存在则直接添加到数组末尾。
setArray(newElements);
return true;
} finally {
lock.unlock(); //最终都要释放锁
}
}
注意:CopyOnWriteArraySet每次add都要遍历数组,性能要低于CopyOnWriteArrayList。
4、删除元素
public boolean remove(Object o) {
return al.remove(o);//调用CopyOnWriteArrayList的remove(Object o)方法
}
5、遍历所有元素
public Iterator<E> iterator() {
return al.iterator(); //调用CopyOnWriteArrayList的iterator方法
}
CopyOnWriteArraySet底层就是一个CopyOnWriteArrayList
CopyOnWriteArraySet在add元素的时候要遍历一遍数组,从而起到不添加重复元素的作用,但是由于要遍历数组,效率也会低于CopyOnWriteArrayList的add
Set集合没有按索引直接获取或修改或添加或删除的方法(get(int index),add(int index,E e),set(int index,E e),remove(int index))。
以上是关于CopyOnWriteArraySet源码分析的主要内容,如果未能解决你的问题,请参考以下文章
CopyOnWriteArrayList,CopyOnWriteArraySet源码分析