HashSet 是 Java 集合框架中的一个实现类,用于存储无序、唯一的元素。在源码分析 HashSet 时,可以从构造方法、添加元素、删除元素和查找元素这几个方面入手,深入了解其实现原理。

一、构造方法
HashSet 的构造方法有多种重载形式,可以根据需要选择不同的构造方法进行实例化。比较常用的是无参构造方法 HashSet() 和带有容量和加载因子的构造方法 HashSet(int initialCapacity, float loadFactor)。其中,初始容量参数用于指定初始大小,加载因子参数用于指定哈希表的负载因子,默认为 0.75。当 HashSet 中存储的元素个数超过负载因子与初始容量的乘积时,HashSet 会自动进行扩容。

例如,无参构造方法的源码如下所示:

javapublicHashSet(){map=wHashMap<>();}

在无参构造方法中,创建了一个 HashMap 对象作为 HashSet 的底层实现,从而实现了 HashSet 的特性。

二、添加元素
HashSet 中添加元素时,会调用 HashMap 的 put 方法实现。在 put 方法中,首先会判断要添加的元素是否已经存在于 HashMap 中,如果存在则返回值不为空,并将新加入的元素覆盖旧值;如果不存在,则将元素添加到 HashMap 的 key 集合中,与此同时,把 HashSet 中的 value 值都设置为同一个 Object 对象,比如:

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}
Java

其中 PRESENT 是一个静态的 Object 对象,用于作为 value 值。可以看出,HashSet 中的元素实际上是存储在 HashMap 的 key 集合中的,而 value 值则是同一个对象。

三、删除元素
HashSet 中删除元素时,会调用 HashMap 的 remove 方法实现。在 remove 方法中,首先会根据元素的 hashCode 确定在 HashMap 中的位置,然后再根据 equals 方法判断元素是否相等。如果相等,则将该元素从 HashMap 中删除。

例如,remove 方法的源码如下所示:

public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
}
Java

其中,o 为待删除的元素。当调用 remove 方法成功删除元素时,返回值为 PRESENT。

四、查找元素
HashSet 中查找元素时,会调用 HashMap 的 containsKey 方法实现。在 containsKey 方法中,首先会根据元素的 hashCode 确定在 HashMap 中的位置,然后再根据 equals 方法判断元素是否存在于 HashMap 中。

例如,contains 方法的源码如下所示:

public boolean contains(Object o) {
    return map.containsKey(o);
}
Java

其中,o 为待查找的元素。当调用 contains 方法时,如果元素存在于 HashMap 中,则返回 true;否则返回 false。

通过对 HashSet 源码的分析,我们可以了解到 HashSet 是通过 HashMap 实现的,它的添加、删除和查找元素操作都是基于 HashMap 的实现。HashSet 的底层使用了 HashMap 的键来存储元素,而 HashMap 中的键则与 HashSet 中的值是绑定在一起的。因此,在使用 HashSet 时,我们可以充分利用 HashSet 的去重特性和 HashMap 的高效查找特性,提高程序的性能和效率。