java常见Set解析HashSet & LinkedHashSet & ConcurrentSkipListSet & CopyOnWriteArraySet——java技术栈系列文章

IT黑名单 2017-3-2 16:20:27

目录

HashSet

HashSet内部实现是基于HashMap的,它只使用了HashMap的key,将元素作为key存入HashMap,相应的方法也是调用HashMap的实现。
HashSet.java

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();

    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
}

需要注意的是HashSet的contains在元素的hashCode和equals都相等时才返回true。

LinkedHashSet

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
    // LinkedHashSet构造
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }
    ...
}

// 对应上面super(int, float, true)
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}

从代码可以看出,LinkedHashSet底层使用LinkedHashMap实现链表的有序。同时继承了HashSet,也具有HashSet的特性。关于HashMap和LinkedHashMap的实现可以参见HahsMap&LinkedHashMap

ConcurrentSkipListSet

private final ConcurrentNavigableMap<E,Object> m;
public ConcurrentSkipListSet() {
    // 利用ConcurrentSkipListMap实现构造
    m = new ConcurrentSkipListMap<E,Object>();
}
ConcurrentSkipListSet基于ConcurrentSkipListMap实现,线程安全,跟ConcurrentSkipListMap一样在高并发场景下表现优异。

CopyOnWriteArraySet

ConcurrentSkipListSet基于CopyOnWriteArrayList实现,那么它本身也具有CopyOnWriteArrayList的一切特性:
        线程安全;
        因为要复制整个数组,所以写操作开销很大;
        使用迭代器进行遍历的速度很快,并且不会与其他线程发生冲突。在构造迭代器时,迭代器依赖于不变的数组快照。
    ConcurrentSkipListSet适用于大小很小,读远高于写的场景,迭代器支持hasNext(), next()等不可变操作,但不支持可变 remove()等操作。CopyOnWriteArrayList文章可以参考:List线程安全——java技术栈系列文章


转载请注明来源【IT黑名单

本文链接:http://blog.itblacklist.cn/20170302/8446.html

© Copyright 2016 IT黑名单 Inc.All Rights Reserved. 豫ICP备15018592号-2