CopyOnWriteArraySet源码解析
此文已由作者赵计刚授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
注:在看这篇文章之前,如果对CopyOnWriteArrayList底层不清楚的话,建议先去看看CopyOnWriteArrayList源码解析。
http://www.cnblogs.com/java-zhao/p/5121944.html
1、对于CopyOnWriteArraySet需要掌握以下几点
创建:CopyOnWriteArraySet()
添加元素:即add(E)方法
删除对象:即remove(E)方法
遍历所有对象:即iterator(),在实际中更常用的是增强型的for循环去做遍历
注:
CopyOnWriteArraySet(不可添加重复元素)底层是CopyOnWriteArrayList(可添加重复元素)。
Set集合没有按索引直接获取或修改或添加或删除的方法(eg.get(int index),add(int index,E e),set(int index,E e),remove(int index))
2、创建
public CopyOnWriteArraySet()
使用方法:
Set<String> strSet = new CopyOnWriteArraySet<String>();
源代码:
private final CopyOnWriteArrayList<E> al;//底层数据结构
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
注意点:
CopyOnWriteArraySet底层就是一个CopyOnWriteArrayList
3、添加元素
public boolean add(E e)
使用方法:
strSet.add("hello")
源代码:
/**
* 循环遍历旧数组,若有与e相同的值,return false
* 若没有,向最后插值
*/
public boolean add(E e) {
return al.addIfAbsent(e);
}
CopyOnWriteArrayList的addIfAbsent(E e)
public boolean addIfAbsent(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
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; // 如果有,直接返回
else
newElements[i] = elements[i];
}
newElements[len] = e;//如果没有,就赋值
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
注:这一块儿的源代码很简单,只要你看了CopyOnWriteArrayList源码解析中的add方法就能看懂
注意点:
CopyOnWriteArraySet每次add都要遍历数组,性能要低于CopyOnWriteArrayList
4、删除元素
public boolean remove(Object o)
使用方法:
strSet.remove("hello")
源代码:
/**
* 调用CopyOnWriteArrayList的remove(Object o)方法
*/
public boolean remove(Object o) {
return al.remove(o);
}
5、遍历所有元素
public Iterator<E> iterator()
使用方法:见上一章《CopyOnWriteArrayList源码解析》
源代码:
/**
* 调用CopyOnWriteArrayList的iterator()
*/
public Iterator<E> iterator() {
return al.iterator();
}
剩余的源代码见上一章《CopyOnWriteArrayList源码解析》
总结:
CopyOnWriteArraySet底层就是一个CopyOnWriteArrayList
CopyOnWriteArraySet在add元素的时候要遍历一遍数组,从而起到不添加重复元素的作用,但是由于要遍历数组,效率也会低于CopyOnWriteArrayList的add
Set集合没有按索引直接获取或修改或添加或删除的方法(eg.get(int index),add(int index,E e),set(int index,E e),remove(int index))
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 浅谈代码结构的设计
CopyOnWriteArraySet源码解析的更多相关文章
- 第四章 CopyOnWriteArraySet源码解析
注:在看这篇文章之前,如果对CopyOnWriteArrayList底层不清楚的话,建议先去看看CopyOnWriteArrayList源码解析. http://www.cnblogs.com/jav ...
- HashSet、CopyOnWriteArraySet、ConcurrentSkipListSet源码解析(JDK1.8)
目录 HashSet源码解析 HashSet简单使用的demo HashSet中的变量 HashSet的构造函数 HashSet的add方法 HashSet的iterator方法 HashSet的si ...
- ArrayList、CopyOnWriteArrayList源码解析(JDK1.8)
本篇文章主要是学习后的知识记录,存在不足,或许不够深入,还请谅解. 目录 ArrayList源码解析 ArrayList中的变量 ArrayList构造函数 ArrayList中的add方法 Arra ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- Spring IoC源码解析——Bean的创建和初始化
Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...
随机推荐
- oracle 笔记DBA
1.1oracle开启归档 关闭数据库 SQL>archive log list; SQL>shutdown immediate; SQL>startup mount ; SQL&g ...
- BP神经网络的理论理论常识
BP神经网络的简单结构:输入层.一个或者多个隐层.输出层.图如下: 在图中,涉及到的参数有:X1--Xn为输入参数.输入参数通过输入层和隐层之间的的链接权重进行计算,到达隐层. 隐层的输入参数通过隐层 ...
- kbmmw 的HTTPSmartService 上传文件到服务器端
前面我写过了 HTTPSmartService 使用介绍,可以参见以前的文章. 前一向有同学问如何在http 页面表单上上传文件.一直没有时间回答,自己简单做了例子, 发现无法实现功能,今天花了一天时 ...
- 844. Backspace String Compare
class Solution { public: bool backspaceCompare(string S, string T) { int szs=S.size(); int szt=T.siz ...
- mysql字符串类型数据
字符串类型是在数据库中存储字符串的数据类型,字符串类型包括char,varchar,text,enum和set. OK,我们来一个一个的看下上面提到的几种类型. char类型和varchar类型 ch ...
- 在平台中使用JNDI 数据源
有些情况下为了系统的安全性考虑,可以将数据源配置成JNDI,在程序中只需要使用 容器的JNDI路径就可以了. 配置方法 1.在容器中配置数据源 <Context path="/&quo ...
- vue 开发系列(八) 动态表单开发
概要 动态表单指的是我们的表单不是通过vue 组件一个个编写的,我们的表单是根据后端生成的vue模板,在前端通过vue构建出来的.主要的思路是,在后端生成vue的模板,前端通过ajax的方式加载后端的 ...
- Office2013 如何安装Matlab notebook
Office2013 如何安装Matlab notebook 听语音 浏览:912 | 更新:2014-09-16 07:02 1 2 3 4 5 6 7 分步阅读 Office2013(64bit) ...
- js判断软键盘是否开启弹出
移动端关于页面布局,如果底部有position:fixed的盒子,又有input,当软键盘弹出收起都会影响页面布局.这时候Android可以监听resize事件,代码如下,而ios没有相关事件. va ...
- 学以致用十二-----YouCompeteMe巨坑
接上一篇,通过这几天的不断尝试,发现一个无法解决的问题.至于我安装成功的那台,我至今不知道是安装了哪一步导致成功的. 首先,我在.vimrc里加上了 Plugin 'Valloric/YouComp ...