美文网首页
剖析Java 集合框架⑨-Set

剖析Java 集合框架⑨-Set

作者: 李元霸抢貂蝉 | 来源:发表于2021-01-09 10:30 被阅读0次

    Set概括

    前面详细介绍了 ListMap 常用的实现类和源码,下面进入另一个常用的集合类型- Set。主要是存放不重复的元素集合

    HashSet

    望文生意,跟HashMap很像,确实是的,HashSet 组合了 HashMap,很多功能都是操作这个成员变量 HashMap实现的。

    可以先了解前篇 HashMap

    看下成员变量:

    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
        // 底层是使用HashMap 实现的
        private transient HashMap<E,Object> map;
    
        // HashMap里面 所有的value 存放的就是这个空的object
        private static final Object PRESENT = new Object();
    

    下面再来看看构造方法:

       public HashSet() {
            map = new HashMap<>();
        }
    
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            addAll(c);
        }
    
        public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
        }
    
        public HashSet(int initialCapacity) {
            map = new HashMap<>(initialCapacity);
        }
    
        // LlinkedHashSet 会调用改构造方法
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
    

    可以看到,很简单的代码,就是实例化HashMap,而最后一个构造方法,我们发现不是publish的,实际是LinkedHashSet会调用的。
    再来看看一下常用方法:

      // 添加方法
       public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
     
      // 删除方法
        public boolean remove(Object o) {
            return map.remove(o)==PRESENT;
        }
    
      // 是否包含
      public boolean contains(Object o) {
            return map.containsKey(o);
        }
    

    可以看到实际都是调用的 HashMap 的方法。

    LinkedHashSet

    有了 HashSet的分析经验,再来看 LinkedHashSet 轻而易举。底层就是 LinkedHashMap

    可以先了解 LinkedHashMap

    public class LinkedHashSet<E>
        extends HashSet<E>
        implements Set<E>, Cloneable, java.io.Serializable {
    
        private static final long serialVersionUID = -2851667679971038690L;
    
        public LinkedHashSet(int initialCapacity, float loadFactor) {
            super(initialCapacity, loadFactor, true);
        }
    
        public LinkedHashSet(int initialCapacity) {
            super(initialCapacity, .75f, true);
        }
    
        public LinkedHashSet() {
            super(16, .75f, true);
        }
    

    可以看到 LinkedHashSet 直接继承了 HashSet,所以 super 调用的 HashSet的构造方法。

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
    

    HashSet 一样,核心方法都是调用的 map 这个成员变量的方法。

    TreeSet

    支持排序,无重复的 集合。和 HashSet 一样,底层也是直接使用 map 实现。

    可以先了解 TreeMap

    public class TreeSet<E> extends AbstractSet<E>
        implements NavigableSet<E>, Cloneable, java.io.Serializable
    {
       // TreeMap实现了NavigableMap
        private transient NavigableMap<E,Object> m;
    
        // 使用map时 存放的value
        private static final Object PRESENT = new Object();
    
        TreeSet(NavigableMap<E,Object> m) {
            this.m = m;
        }
    
        public TreeSet() {
            this(new TreeMap<E,Object>());
        }
    
        public TreeSet(Comparator<? super E> comparator) {
            this(new TreeMap<>(comparator));
        }
    
        public TreeSet(Collection<? extends E> c) {
            this();
            addAll(c);
        }
    
        public TreeSet(SortedSet<E> s) {
            this(s.comparator());
            addAll(s);
        }
    

    无需额外加注解,很简单的代码。底层就是调用TreeMap来操作。基于 NavigableMap也能做一些导航,比如倒叙等操作。

    总结

    Set 是存放一堆不重复元素的集合,底层都是对应 Map 实现的。

    量变引发质变,经常进步一点点,期待蜕变的自己。

    相关文章

      网友评论

          本文标题:剖析Java 集合框架⑨-Set

          本文链接:https://www.haomeiwen.com/subject/jiqcaktx.html