以HashSet为例:
private transient HashMap<E,Object> map; private static final Object PRESENT = new Object();//注意这个变量,待会会用到 //这个是经常使用到的构造器,可以发现无论是哪一个构造器,HashSet的底层实现都是创建了一个HashMap 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); }
从add方法剖析:
public boolean add(E e) { //PRESENT是一个虚拟值,是为了HashMap实现HashSet的一个假设的值 return map.put(e, PRESENT)==null; }
可以看出:HashSet的底层是由HashMap实现的,而HashSet的add方法,是将元素作为map的key进行存储的,因为map的key不会重复,所以HashSet中的元素也不会重复。