博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CopyOnWriteArraySet源码解析
阅读量:7111 次
发布时间:2019-06-28

本文共 2468 字,大约阅读时间需要 8 分钟。

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

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

注:在看这篇文章之前,如果对CopyOnWriteArrayList底层不清楚的话,建议先去看看CopyOnWriteArrayList源码解析。

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
 strSet = new CopyOnWriteArraySet
();

源代码:

    private final CopyOnWriteArrayList
 al;//底层数据结构    public CopyOnWriteArraySet() {        al = new CopyOnWriteArrayList
();    }

注意点:

  • 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
 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))

更多网易技术、产品、运营经验分享请。

相关文章:

【推荐】 

转载地址:http://zelhl.baihongyu.com/

你可能感兴趣的文章
Android 签名出错
查看>>
.net 获得txt内容
查看>>
顺序存储的队列实现(CPP)
查看>>
《关键字选取三步走:最后一步,一个页面多次使用+多次重新加载。
查看>>
zookeeper 常用
查看>>
ES6 new syntax features
查看>>
.NET Core 1.0会不会成为Vista?真为他捏一把汗
查看>>
Android 实现App会话超时设计
查看>>
sparkStreaming SQL黑名单过滤
查看>>
S3C6410 驱动18b20简单测试,时序
查看>>
php sendcloud 发送邮件
查看>>
IOS block dispatch_queue
查看>>
OpenGL超级宝典笔记——贝塞尔曲线和曲面
查看>>
自学篇之----jquery 添加和删除内容
查看>>
eclipse和tomcat搭建
查看>>
Android移动端音视频的快速开发教程(五)
查看>>
每天进步一点点- lsof 命令查找指定用户、进程、端口打开的文件
查看>>
漫谈C语言及如何学习C语言
查看>>
string,stringbuffer,stringbuild详解
查看>>
Redis主从集群的Sentinel配置
查看>>