一、源码解析
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(); //构造函数。 new 一个空的 HashMap(hashmap 默认的初始化容量是 16,默认加载因子是 0.75)。 public HashSet() { map = new HashMap<>(); } // 构造函数。new 一个 HashMap并且为其添加一个 collection。根据 collection 的大小来自定义初始化容量 public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } // 构造函数。new 一个空的 HashMap,自定义初始化容量和加载因子 public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } // 构造函数。new 一个空的 HashMap,自定义初始化容量 public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } // 得到迭代器,也就是得到了一个 map 的 key 值的集合 public Iterator<E> iterator() { return map.keySet().iterator(); } // 得到元素个数,也就是 hashmap 的元素个数 public int size() { return map.size(); } // 判断是否为空,也就是判断 hashmap 是否为空 public boolean isEmpty() { return map.isEmpty(); } // 判断是否包含某元素,也就是判断 hashmap 的key 中有没有这个元素 public boolean contains(Object o) { return map.containsKey(o); } // 添加一个元素。也就是为 hashmap 添加一个 key 为 e的元素,而 value 是 PRESENT 对象 // 添加成功就会返回 true。不允许添加重复元素(返回 false)。 public boolean add(E e) { return map.put(e, PRESENT)==null; } // 删除一个元素 public boolean remove(Object o) { // hashmap 根据 key 删除这个元素,如果删除成功,就会返回这个元素而且必定是 PRESENT。 return map.remove(o)==PRESENT; } // 清空集合,也就是 map 清空集合 public void clear() { map.clear(); } }
二、总结
1). HashSet 实际上就是维护了一个 HashMap。HashSet 的元素对应的是 HashMap 中的 key,另外这个 HashMap 所有 key 对应的 value 都是 PRESENT。
2). 由于 HashSet 是一个 HashMap 的所有 key 的集合,因为 key 能为空,不能重复,所以 HashSet 也是允许元素为空,不允许重复元素。
就这样吧,如果对 HashMap 理解透彻,HashSet 就会很简单了。
~~