HashSet源代码分析(JDK1.8)
程序员文章站
2022-06-07 13:36:21
...
首先来看一下HashSet类的定义、常用构造方法、常用的类成员方法以及内部的成员变量:
HashSet类的定义如下:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
由上述代码可见,HashSet扩展了AbstractSet类,并实现了Set、Cloneable、Seriablizable接口。
HashSet内部的私有成员变量如下:
//内部实际上采用HashMap存储元素。
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
常用的构造方法如下:
HashSet();
HashSet(Collection<? extends E> c);
HashSet(int initialCapacity);
HashSet(int initialCapacity,float loadFactor);
常用的类成员方法如下:
//添加元素
boolean add(E e);
//获取元素
boolean contains(Object o);
boolean isEmpty();
Iterator<E> iterator();
int size();
//移除元素
boolean remove(Object o);
下面将根据源码对上述方法进行分析:
1. 构造方法
//构造一个新的空Set,内部的map指向一个默认大小为16,默认加载因子为0.75的HashMap实例。
public HashSet() {
map = new HashMap<>();
}
//构造一个HashMap,容量必须大于等于16;
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c); //addAll方法继承自AbstractCollection,通过循环调用add方法
}
//创建指定容量和装载因子的HashMap
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
//指定容量,采用默认装载因子0.75的HashMap
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
2. 元素的添加
2.1 add方法
public boolean add(E e) {
return map.put(e, PRESENT)==null; //直接调用HashMap的put方法,通过返回值为null判断元素e是否原来就已经存在,PRESENT是final常量,主要用于map中键值对的值,
}
3. 元素的获取
3.1 contains方法
public boolean contains(Object o) {
return map.containsKey(o); //同样是直接调用map的contains方法
}
3.2 isEmpty方法
public boolean isEmpty() {
return map.isEmpty(); //直接调用map的isEmpty方法
}
3.3 iterator方法
public Iterator<E> iterator() {
return map.keySet().iterator(); //通过调用map的keySet方法,获取键集合的iterator
}
3.4 size方法
public int size() {
return map.size(); //直接调用HashMap的size方法;
}
4. 元素的移除
4.1 remove方法
public boolean remove(Object o) {
return map.remove(o)==PRESENT; //直接调用HashMap的remove方法
}