基于jdk1.8进行分析的。
HashSet集合是不允许重复元素的,怎么保证的呢?结论是:HashSet是借助于HashMap的key不允许重复这个特性来实现的。HashMap是操作键值对,而HashSet是操作HashMap的key完成相关操作,或者这么说,HashSet全部的操作是借助于HashMap经过某种封装得到的。
继承结构
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
可以清楚的看到继承了AbstractSet类,实现了Set接口,Cloneable、Serializable接口。
构造函数
//默认构造方法
public HashSet() {
//可见内部通过HashMap实现的
map = new HashMap<>();
}
//通过集合创建HashSet,可见也是创建一个HashMap,通过addAll方法填充元素
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);
}
//Constructs a new, empty linked hash set.
//解释过来就是,创建一个新的空的hashSet
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
通过上面的构造方法可以看到HashSet是通过有一个HashMap类型的map成员属性,通过操作HashMap实现的。
成员属性
//序列化的时候使用
static final long serialVersionUID = -5024744406713321676L;
//成员属性map
private transient HashMap<E,Object> map;
//HashMap 为<key, value>的键值对, 既然HashSet的值就是HashMap的key,
//那么HashMap的值呢,当然就是这个PRESENT啦
private static final Object PRESENT = new Object();
成员方法
add(E e)
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
可见是通过调用map的put方法实现的。就是将要添加的元素作为map的key,常量PRESENT作为value保存在HashMap对象中即可。有一点需要我们注意的是:这个add方法有返回值,返回值由map的put方法决定。当map调用put(key,value)方法时,如果存在key后,则map的put方法会返回此key对应的oldValue,add就会返回false。
iterator()
public Iterator<E> iterator() {
return map.keySet().iterator();
}
HashSet并没有提供类似于get的方法,只提供的获取访问元素的迭代器对象。iterator方法也是委托给了map,获取map的key集合的迭代器。
其他方法
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean contains(Object o) {
return map.containsKey(o);
}
public void clear() {
map.clear();
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
可以看到都是通过操作map来实现的。剩下的方法如:readObject、writeObject、clone等方法就不再一一列举了。