概览
1 2 3
| public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
|
值得注意的是HashSet底层是基于HashMap来实现的。
HashSet是一个集合,集合是没有重复的元素的,不能保证顺序的。而且HashSet是非同步的。
它的继承体系如下

属性
1 2 3 4
| private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
|
上文已经提到HashSet的底层是采用HashMap来实现的,但是只用到了key,它使用一个静态的对象PRESENT来填充value,其实可以使用null来填充value的,因为HashMap是支持空键和空值的。我的猜想这样的设计虽然会浪费一点点内存,但是可以避免出现因为操作失误出现空指针异常。
构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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); }
|
HashSet公开的构造器的主要的工作就是初始化HashMap。这就不赘述了。
方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public boolean add(E e) { return map.put(e, PRESENT)==null; }
public boolean remove(Object o) { return map.remove(o)==PRESENT; }
public void clear() { map.clear(); }
public boolean contains(Object o) { return map.containsKey(o); }
public boolean isEmpty() { return map.isEmpty(); }
public int size() { return map.size(); }
public Iterator<E> iterator() { return map.keySet().iterator(); }
|
这些方法也都是调用HashMap的方法,基本没什么说的,看来HashMap很重要啊。