Java集合——HashSet

222 阅读1分钟

简述

在写HashMap的时候提到过Set是基于Map实现的,HashSet基于HashMap实现,将HashSet的数据作为HashMap的Key值保存,所以HashSet中元素不可重复,无序,允许null元素,线程不安全。

源码分析

HashSet字段


    //基于HashMap实现
    private transient HashMap map;
    
    //虚拟一个value
    private static final Object PRESENT = new Object();

构造方法


    /**
     * 默认无参构造,初始化了一个空的HashMap
     */
    public HashSet() {
        map = new HashMap<>();
    }
    
    /**
     * 指定容量构造
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
    
    /**
     * 指定容量和负载因子
     */
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    
    /**
     * 指定容量、负载因子构造一个新的集合,非public有访问权限
     * 只有LinkedHashSet涉及到
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
    
    /**
     * 指定collection集合构造
     */
    public HashSet(Collection c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

从这里我们可以看出HashSet基于HashMap实现

add方法

用HashMap的put方法完成HashSet的add操作,因为HashMap的key不可重复,所以HashSet中的元素不会重复,源码如下


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

remove方法

调用HashMap的remove方法


    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

contains方法

因为HashSet的元素都作为HashMap的Key值保存,所以查询是否包含此key


    public boolean contains(Object o) {
        return map.containsKey(o);
    }

迭代

获取HashMap的KeySet的迭代器


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

clone方法

属于浅克隆


    public Object clone() {
        try {
            HashSet newSet = (HashSet) super.clone();
            newSet.map = (HashMap) map.clone();
            return newSet;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }

总结

HashSet基于HashMap实现,与HashMap一样无序,线程不安全,利用HashMap的key不可重复从而实现HashSet不含重复元素