美文网首页
10.HashSet

10.HashSet

作者: 木有鱼丸啦 | 来源:发表于2019-06-27 15:51 被阅读0次
    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
    
        //HashMap ? 没错,HashSet就是通过HashMap保存数据, HashSet的值就是HashMap的key
        private transient HashMap<E,Object> map;
        
        //HashMap 为<key, value>的键值对, 既然HashSet的值就是HashMap的key, 那么HashMap的值呢,当然就是这个PRESENT啦
        private static final Object PRESENT = new Object();
        
        //下面这一系列的构造方法都是创建HashMap, 之前已经介绍过HashMap, 这儿就不再详说了
        public HashSet() {
            map = new HashMap<>();
        }
    
        //将一个已知的collection转换为HashSet
        public HashSet(Collection<? extends E> c) {
            //这儿的HashMap的参数为什么这么写?
            //上次介绍HashMap的时候可知,如果没有指定HashMap的capacity, 那么默认的就是16
            //根据 threshold = capacity * loadFactor, 可以计算出 capacity
            //Math.max((int) (c.size()/.75f) + 1, 16) 这个意思就是capacity如果没超过16, 那么就直接使用默认的16
            map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
            //将已知的collection转换为HashSet的方法
            //addAll方法是HashSet的父类AbstractCollection的方法,为了便于阅读,会将代码粘贴在下面
            addAll(c);
        }
    
        public HashSet(int initialCapacity, float loadFactor) {
            map = new HashMap<>(initialCapacity, loadFactor);
        }
    
    
        public HashSet(int initialCapacity) {
            map = new HashMap<>(initialCapacity);
        }
    
    
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<>(initialCapacity, loadFactor);
        }
        
        //addAll方法是HashSet的父类AbstractCollection的方法
        public boolean addAll(Collection<? extends E> c) {
            boolean modified = false;
            for (E e : c)
                //此处的add方法由HashSet重写实现
                if (add(e))
                    modified = true;
            return modified;
        }
        
        //HashSet的核心方法来了, 没错,就这么简单
        public boolean add(E e) {
            //应证了上面所说的key为HashSet的值
            return map.put(e, PRESENT)==null;
        }
        
        //剩下这些方法都是跟Map相关的了,只要熟悉了HashMap, 那就太简单了,就不说了
        public boolean remove(Object o) {
            return map.remove(o)==PRESENT;
        }
    
        public void clear() {
            map.clear();
        }
        
    }
    

    HashSet的源码如此简单。下面还是对HashSet的源码作一个总结吧:

    1. HashSet基于HashMap实现, 以HashSet的值作为HashMap的一个key, 以一个Object对象常量作为HashMap的值。

    2. 根据HashMap的特性,可以推敲出:HashSet允许拥有1个为null的值, HashSet的值不可重复。

    3. 在创建HashSet的时候,如果合适,最好指定其内部HashMap的 capacity和loadFactory的值, 至于原因,在介绍HashMap的时候,提到过。

    相关文章

      网友评论

          本文标题:10.HashSet

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