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的生命周期进行管理的轻量级容器 ...
随机推荐
- m序列
产生m序列移位寄存器是一种逻辑电路,1阶,2阶...的电路图各不相同. 一般使用本原多项式计算出各阶数电路图. 一般的多项式为 f(x) = c0 * x^0 + c1 * x^1 + c2 * x^ ...
- 20155312 张竞予 2006-2007-2 《Java程序设计》第四周学习总结
20155312 2006-2007-2 <Java程序设计>第四周学习总结 课堂笔记 Ctrl+shift+T调出三个窗口,分别是"vi编写代码","jav ...
- one or more
想到以后如果一直都是这样,那么以后的生活是多么多么可怕啊. 感觉毫无期盼.没有意义. 如果变得理所当然那是多么多么让人害怕的事,吓得让人发抖. 所以在以后漫长的岁月里,还是一个人吧 如果相互看不惯,感 ...
- LSTM长短期记忆神经网络模型简介
LSTM网络也是一种时间递归神经网络,解决RNN的长期依赖关系. RNN模型在训练时会遇到梯度消失或者爆炸的问题,训练时计算和反向传播,梯度倾向于在每一时刻递增或递减,梯度发散到无穷大或者0..... ...
- day13作业—(登录注册)
2.写一个函数完成三次登陆功能: 用户的用户名密码从一个文件register中取出. register文件包含多个用户名,密码,用户名密码通过|隔开,每个人的用户名密码占用文件中一行. 完成三次验证, ...
- day09作业—函数进阶
# 2.写函数,接收n个数字,求这些参数数字的和.(动态传参) def func1(*args): sum = 0 for i in args: sum += i print(sum) func1(1 ...
- struct sk_buff和struct net_device
1.struct sk_buff 1.1概念 sk_buff是是linux内核中描述数据包的结构体,可在各个协议层之间传递,如数据链路层.网络层.运输层 1.2成员组成 1)布局 sk_buff是一个 ...
- python模块:shutil
"""Utility functions for copying and archiving files and directory trees. XXX The fun ...
- vba中布尔类型、字符串操作
在vba中,bool类型数据可以参与数学运算,true为-1,false为0 Sub mysub() Dim mybool As Boolean Debug.Print Debug.Print myb ...
- 【1】ASP.NET异步(1)
图标说明了异步的基础认识. 1.如果没有Ajax,提交之后整个页会刷新(左图).右图所示的虚线范围区域加入了ajax技术,提交之后只更新了虚线区域的内容,这样看比较直白. <form>①& ...