1. 概述

HashSet 保证元素不重复的集合,查询元素、新增元素、删除元素的时间复杂度均为 O(1)。

HashSet 底层的数据结构为 HashMap,map 中存储的键值对,key 为 Set 集合中的元素,value 使用同一个静态常量(即下面代码中的PRESENT);

private transient HashMap<E,Object> map;

private static final Object PRESENT = new Object();

HashSet 新增元素使用 HashMap 的 put 方法不断的去替换以前的元素(保证元素不重复),HashMap 的 put 时间复杂度为 O(1),所以 HashSet 新增元素的时间复杂度也为 O(1); HashSet 查询是否存在元素使用 HashMap 的 containsKey 方法,所以时间复杂度为 O(1);HashSet 删除元素 使用 HashMap 的 remove 方法, 时间复杂度也为 O(1);

2. 构造函数

无参构造函数,初始化一个空的 hashMap;

public HashSet() {
        map = new HashMap<>();
    }

使用集合构造一个set,容器大小为集合大小的4/3倍和16的最大值:

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);
    }

default 级别的构造函数,供 LinkedHashSet 使用;

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

3. 方法

集合元素的迭代器,返回的数据是无序的:

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

是否包含某元素,调用 HashMap 的 containsKey 方法;

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

新增元素,使用HashMap的put方法:

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

移除元素,使用HashMap的remove方法:

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

浅拷贝:

@SuppressWarnings("unchecked")
    public Object clone() {
        try {
            HashSet<E> newSet = (HashSet<E>) super.clone();
            newSet.map = (HashMap<E, Object>) map.clone();
            return newSet;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }