Java集合5-HashSet

HashSet:基于哈希表实现的集合,用于存储不重复的元素。

HashSet<String> set = new HashSet<>();
set.add("Item 1");
set.add("Item 2");

HashSet 是一个不允许存储重复元素的集合,它的实现比较简单,只要理解了 HashMapHashSet 就水到渠成了。HashSet 的底层实现是基于 HashMap 的,它实际上是通过 HashMap 来实现的,只不过在 HashSet 中只使用了 HashMap 的键,而没有使用值。

  1. HashMap:HashSet 内部维护了一个 HashMap 对象,作为存储元素的载体。
  2. 存储元素:当向 HashSet 中添加元素时,实际上是将该元素作为 HashMap 的键存储,而值则存储为一个常量,比如 PRESENT = new Object()
  3. 哈希表:HashMap 的键是唯一的,因此 HashSet 中不会有重复元素。HashSet 利用 HashMap 键的唯一性来保证其中不会有重复元素。
  4. 去重:当调用 HashSet 的 add() 方法时,实际上是调用了 HashMap 的 put() 方法,将元素作为键存储到 HashMap 中,如果这个键已经存在,put() 方法会返回旧值,如果是新键,则返回 null。这样就保证了 HashSet 中不会有重复元素。
  5. 查找:当调用 HashSet 的 contains() 方法时,实际上是调用了 HashMap 的 containsKey() 方法来判断元素是否存在。

成员变量

首先了解下 HashSet 的成员变量:

    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

发现主要就两个变量:

  • map :用于存放最终数据的。
  • PRESENT :是所有写入 map 的 value 值。

构造函数

    public HashSet() {
        map = new HashMap<>();
    }
    
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }    

构造函数很简单,利用了 HashMap 初始化了 map

add

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

比较关键的就是这个 add() 方法。 可以看出它是将存放的对象当做了 HashMap 的健,value 都是相同的 PRESENT 。由于 HashMapkey 是不能重复的,所以每当有重复的值写入到 HashSet 时,value 会被覆盖,但 key 不会受到影响,这样就保证了 HashSet 中只能存放不重复的元素。

总结

HashSet 的原理比较简单,几乎全部借助于 HashMap 来实现的。由于 HashSet 的底层是基于 HashMap 实现的,因此具有 HashMap 的特性,如高效的添加、查找操作(平均情况下为 O(1)),去重功能等。不过需要注意的是,HashSet 并不保证元素的顺序,元素存储的顺序与插入顺序可能不同,因为它是根据哈希值存储的。

所以 HashMap 会出现的问题 HashSet 依然不能避免。

你可能感兴趣的:(java,开发语言)