Java集合源码实现五:HashSet(jdk1.8)
类继承关系:
(*=>:接口实现)
java.lang.Object
–java.util.AbstractCollection =>Collection
–java.util.AbstractSet =>Set
–java.util.HashSet =>Set, Cloneable, java.io.Serializable
什么是HashSet
实现了Set接口,由一个哈希表(实际上是一个HashMap实例)支持。对集合的迭代次序没有保证,允许null 元素但不允许有重复元素。
HashSet数据结构
HashSet是通过调用HashMap实现的,所储存的值就是HashMap中的key值,所以HashSet的数据结构与HashMap的数据结构相同。(点击跳转Java集合源码实现三:HashMap (jdk1.8))。
源码分析:
1.类继承实现
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
//方法....
}
可克隆,可序列化
2.成员变量
/**
* 存储元素的map HashSet实质上就是一个HashMap
*/
private transient HashMap<E,Object> map;
/**
* 定义一个虚拟值作为HashMap的value
*/
private static final Object PRESENT = new Object();
3.主要方法
构造方法
1.
/**
* 构造一个无参数的HashSet,实际上就是初始化了一个默认参数的HashMap
*/
public HashSet() {
map = new HashMap<>();
}
以下几个构造方法也同理分别初始化不同的HashMap,详情请参考HashMap篇
2.
/**
*
*/
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
3.
/**
*
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
4.
/**
*
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
5.
/**
* 给子类LinkedHashSet使用的 所以初始化的也是LinkedHashMap
* @param dummy 标记作用 区分开其他构造方法 没实际意义
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
添加元素
/**
* 调用HashMap的添加方法
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
添加的元素实际就是添加hashMap的key值,因为key值是不能重复的,所以HashSet中的元素不能重复
删除元素
/**
* 调用HashMap的删除方法
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}