此文已由作者赵计刚授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

注:在看这篇文章之前,如果对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源码解析的更多相关文章

  1. 第四章 CopyOnWriteArraySet源码解析

    注:在看这篇文章之前,如果对CopyOnWriteArrayList底层不清楚的话,建议先去看看CopyOnWriteArrayList源码解析. http://www.cnblogs.com/jav ...

  2. HashSet、CopyOnWriteArraySet、ConcurrentSkipListSet源码解析(JDK1.8)

    目录 HashSet源码解析 HashSet简单使用的demo HashSet中的变量 HashSet的构造函数 HashSet的add方法 HashSet的iterator方法 HashSet的si ...

  3. ArrayList、CopyOnWriteArrayList源码解析(JDK1.8)

    本篇文章主要是学习后的知识记录,存在不足,或许不够深入,还请谅解. 目录 ArrayList源码解析 ArrayList中的变量 ArrayList构造函数 ArrayList中的add方法 Arra ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  5. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  7. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  8. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  9. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

随机推荐

  1. 编译sgbm_ros中遇到的问题

    出现的问题 这个会报错 1.解决方法是在文件sudo gedit /usr/local/cuda/include/crt/common_functions.h中注释掉如下 #define __CUDA ...

  2. GC垃圾收集器分类

    参考https://blog.csdn.net/tjiyu/article/details/53983650 Java垃圾收集器组合: 新生代收集器:Serial.ParNew.Parallel Sc ...

  3. SPOJ - NSUBSTR(长度为1-len的字串出现的最大次数

    题意:给你一个字符串,要你输出1-len的字串出现的最大次数. /** @xigua */ #include <stdio.h> #include <cmath> #inclu ...

  4. set集合的排序

    在hibernate的OneToMany的实体关联的时候,one端的set是无序的,可是需要按照顺序来搞的话就比较麻烦了. 下面给出一个例子. Set<DiaryPicture> diar ...

  5. 关于java项目中的XML文件

    一,xml的机制 1.xml文件会在服务器启动的时候进行加载 2.加载完成后根据xml文件里面配置的属性对集成的对象进行属性和行为赋予 3.xml会有很多不同的标签,每个标签都有它特定的含义 二.为什 ...

  6. Vue.js 教程

    http://www.runoob.com/vue2/vue-routing.html

  7. 时间控件My97简单用法

    my97的用法很是简单,项目中用到,查了资料才找到的,简单使用,记一下,方便查阅. 1.添加依赖. <script language="javascript" type=&q ...

  8. .net 根据网址生成静态页

    生成HTML页面代码 public int Htmls(int id) { ; string strHtmlContent = ""; HttpWebRequest request ...

  9. split(),reverse(),join()

     split() 通过把字符串分割成子字符串来把一个 String 对象分割成一个字符串数组. str.split([separator][, limit])示例: "Webkit Moz ...

  10. spring之jdbcTemplate

    spring的另一个功能模块data access对于数据库的支持 spring data access第一个helloword案例: 使用java程序实现访问配置 1.导包 2.测试案例 @Test ...