基于jdk1.7
HashSet继承了AbstractSet,继承了Set、Cloneable、Serializable接口
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
成员变量
之前我一直有记HashSet的特点:存储无序且其中元素不可重复,但是不知道其中的数据结构,它有两个成员变量map和PRESENT 。整个HashSet的实现是基于HashMap数据结构基础上的,HashMap是用来进行存储元素的数据结构,而PRESENT是用于充当HashMap中的value这个角色的,在HashSet中map里所有value都是PRESENT,然后使用key来存储元素,这样就利用了HashMap数据结构key唯一的特点来实现HashSet里元素不可重复的特点。
private transient HashMap<E, Object> map;
private static final Object PRESENT = new Object();
构造方法
HashSet有四种构造方法,HashMap也有四种构造方法,看内部实现知道HashSet的构造方法是对HashMap的构造方法进行的封装。
public HashSet() {
this.map = new HashMap();
}
public HashSet(Collection<? extends E> var1) {
this.map = new HashMap(Math.max((int)((float)var1.size() / 0.75F) + 1, 16));
this.addAll(var1);
}
public HashSet(int var1, float var2) {
this.map = new HashMap(var1, var2);
}
public HashSet(int var1) {
this.map = new HashMap(var1);
}
iterator方法
因为HashSet是一个无序集合,且HashMap的get方法是根据key查找value的,而HashSet的所有value都是一样的PRESENT,,所以HashSet无法封装get方法,仅能提供iterator来实现对于HashSet内部元素进行迭代读取。
public Iterator<E> iterator() {
return this.map.keySet().iterator();
}
size方法
内部封装了HashMap的size方法获取当前容量大小。
public int size() {
return this.map.size();
}
isEmpty方法
内部封装HashMap的isEmpty方法判断是否为控
public boolean isEmpty() {
return this.map.isEmpty();
}
contains方法
内部封装HashMap的containsKey方法,判断key元素是否存在。
public boolean contains(Object var1) {
return this.map.containsKey(var1);
}
add方法
内部封装HashMap的put方法,以静态不可变的PRESENT对象作为value,存入var1作为key。
public boolean add(E var1) {
return this.map.put(var1, PRESENT) == null;
}
remove方法
内部封装HashMap的remove方法,根据传入的key值删除对应的key-value元素,若被删除的value值是PRESENT则返回true
public boolean remove(Object var1) {
return this.map.remove(var1) == PRESENT;
}
clear方法
内部封装HashMap的clear方法,清空map的所有元素。
public void clear() {
this.map.clear();
}
总结
HashSet数据结构是基于HashMap数据结构来实现的,它是无序且不可重复的数据结构,由于实现方式限制,没有封装HashMap的get方法,只有iterator方法来进行迭代查询。
关于HashMap数据结构源码可以参考我的另一篇博客《深入理解HashMap底层原理》