HashSet是Set集合的哈希实现,其继承了AbstractSet抽象类,并实现了Set接口。
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
原理
为了深入理解HashSet的原理,将从成员变量,构造方法,核心方法逐一介绍。
类成员变量
//HashSet内部使用HashMap存储
private transient HashMap<E,Object> map;
//存储在value上的值
private static final Object PRESENT = new Object();
从类成员变量我们可以知道,HashSet内部使用HashMap存储,而PRESENT则是存储在所有key上的value。因此对于HashSet来说,其所有key的value都相同。
构造方法
HashSet一共有5个构造方法。
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(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
可以看到构造方法传入的参数其实就是用于初始化HashMap对象,主要有:initialCapacity(初始化大小),loadFactor(扩容因子)。
这里有一个关键的细节,即第五个方法使用LinkedHashMap实现,而不是用HashMap实现的。
核心方法
对于HashSet来说,其核心方法有add,remove。
来看add方法:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
可以看到add方法直接调用了HashMap对象的put方法。如果Set集合插入成功,那么就返回true,否则返回false。
更多面试资料,JDK文档,阿里巴巴Java开发手册,pdf书籍,视频,公号《Java路》