zoukankan      html  css  js  c++  java
  • 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))


    免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

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


    相关文章:
    【推荐】 浅谈代码结构的设计

  • 相关阅读:
    OnEraseBkgnd、OnPaint与画面重绘
    .编译ADO类DLL时报错的解决方案
    VC列表框样式
    Codeforces 131D. Subway 寻找环树的最短路径
    Codeforces 103B. Cthulhu 寻找奈亚子
    Codeforces 246D. Colorful Graph
    Codeforces 278C. Learning Languages 图的遍历
    Codeforces 217A. Ice Skating 搜索
    Codeforces 107A. Dorm Water Supply 搜图
    Codeforces 263 D. Cycle in Graph 环
  • 原文地址:https://www.cnblogs.com/163yun/p/10151454.html
Copyright © 2011-2022 走看看