前言
之前一篇文章写了 HashMap,那本篇就来写与其十分相关的 HashSet,阅读本篇之前需要阅读 Java集合之 HashMap ,因为 HashSet 的背后就是 HashMap。
一、HashSet 简介
HashSet 是 Set 接口的一种实现,其存储有一个特点就是其中的值都不重复,当然因为其值是经过 hash 操作的 HashSet 内部的元素都是无序的,对于一个值是否存在于 Set 中 HashSet 能够提供优异的查询性能。HashSet 的特殊之处在于其完全是由 HashMap 来实现的只不过所有的 Value 都是同一个 Object 对象并对用户隐藏了 Vaule。
二、HashSet 源码分析
由于 HashSet 是通过 HashMap 实现的因此具体的数据结构和于底层实现可参照 Java集合之 HashMap,本文着重讲解 成员遍历及核心方法
2.1 成员变量
// 第一个成员变量就是 HashMap 这就是我们 HashSet 的底层,值得注意的是泛型方面只指定了 key 的泛型没有指定 value 的因为在 HashSet 中 value 都是同一个
private transient HashMap<E,Object> map;
// 底层 HashMap 的value,所有 <k, v> 组合的 v 都是这个静态的 PRESENT
private static final Object PRESENT = new Object();
2.2 构造方法
构造方法方面非常简单,这里重点阐述一下俩个参数的构造方法,其他方法再看过 HashMap 之后也就明白了
HashSet(int, float)
// initialCapacity HashMap 的初始容量
// loadFactor 的负载因子
// 可以看到 HashSet 的构造函数实际上是在初始化 HashMap
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
2.3 核心方法
HashSet 的核心方法有三个 add(), contains(), remove()
2.3.1 add() 方法
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
可以看到 HashSet 的 add() 其实就是调用了 HashMap 的 put() 方法,需要注意是 value 都是 PRESENT 这个对象。
2.3.2 contains() 方法
public boolean contains(Object o) {
return map.containsKey(o);
}
同样,contains() 方法也是调用 HashMap 中的方法,因为我们的值全都是 Map 中的 key 因此这里调用的是 containsKey() 。
2.3.3 remove() 方法
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
调用 HashMap 的 remove() 方法来删除值。
三、总结
HashSet 至此就结束了,实在是内容非常之少,其主要原因是其完全就是一种特殊的 HashMap(所有的 value 都是同一个值),因此好好的了解 HashMap 之后 HashSet 也就随之理解了。