HashSet 在 Java 中内部是如何工作的

简介: 【8月更文挑战第22天】

HashSet 在 Java 中的内部工作原理

HashSet 是 Java Collections Framework 中一个重要的数据结构,它实现了 Set 接口。它允许你存储唯一元素的集合,并提供了快速和高效的查找、插入和删除操作。HashSet 的底层实现基于哈希表,这是一种使用哈希函数将元素映射到数组索引的数据结构。

哈希表

哈希表是一个数组,其中每个索引都存储一个值。哈希函数用于将元素映射到数组中的索引。哈希函数的目标是将元素均匀地分布在数组中,以最大限度地减少冲突。

哈希冲突

当两个不同的元素哈希到同一个数组索引时,就会发生哈希冲突。为了处理冲突,HashSet 使用一种称为链地址法的技术。在这种方法中,每个数组索引都指向一个链表,其中存储着哈希到该索引的所有元素。

HashSet 的内部结构

HashSet 的内部结构包括以下组件:

  • 哈希表:一个数组,其中每个索引都存储一个链表或 null。
  • 链表:一个双向链表,用于存储哈希到同一个索引的元素。
  • 哈希函数:一个函数,用于将元素映射到哈希表中的索引。
  • 负载因子:一个阈值,当哈希表中元素的数量达到此阈值时,哈希表的大小会增加。

添加元素

向 HashSet 中添加元素涉及以下步骤:

  1. 计算元素的哈希码。
  2. 使用哈希码将元素映射到哈希表中的索引。
  3. 如果该索引处已经有链表,则将元素添加到链表中。
  4. 如果该索引处没有链表,则创建一个新链表并将其添加到该索引处,然后将元素添加到链表中。

查找元素

在 HashSet 中查找元素涉及以下步骤:

  1. 计算元素的哈希码。
  2. 使用哈希码将元素映射到哈希表中的索引。
  3. 如果该索引处有链表,则在链表中搜索元素。
  4. 如果在链表中找到元素,则返回 true;否则返回 false。

删除元素

从 HashSet 中删除元素涉及以下步骤:

  1. 计算元素的哈希码。
  2. 使用哈希码将元素映射到哈希表中的索引。
  3. 如果该索引处有链表,则从链表中删除元素。
  4. 如果链表中没有元素,则将该索引处的链表删除。

负载因子

负载因子是一个阈值,当哈希表中元素的数量达到此阈值时,哈希表的大小会增加。增加哈希表的大小有助于减少哈希冲突并提高性能。负载因子的默认值为 0.75,这意味着当哈希表达到 75% 的容量时,它的大小会增加。

示例

以下示例演示了如何使用 HashSet 来存储和检索元素:

import java.util.HashSet;

public class HashSetExample {
   

    public static void main(String[] args) {
   
        // 创建一个 HashSet
        HashSet<String> hashSet = new HashSet<>();

        // 向 HashSet 中添加元素
        hashSet.add("Apple");
        hashSet.add("Banana");
        hashSet.add("Cherry");
        hashSet.add("Date");
        hashSet.add("Elderberry");

        // 检索元素
        System.out.println("Contains Banana: " + hashSet.contains("Banana"));

        // 遍历 HashSet
        System.out.println("Elements in the HashSet:");
        for (String element : hashSet) {
   
            System.out.println(element);
        }
    }
}

输出:

Contains Banana: true
Elements in the HashSet:
Apple
Banana
Cherry
Date
Elderberry

优点

使用哈希表作为其底层数据结构为 HashSet 带来了以下优点:

  • 快速的查找、插入和删除操作,时间复杂度为 O(1),在平均情况下。
  • 内存效率高,因为它只存储元素本身,而不存储键值对。

缺点

与其他数据结构(如 TreeMap)相比,HashSet 的缺点包括:

  • 无法对元素进行排序。
  • 不允许重复元素。

结论

HashSet 是 Java 中一种有用的数据结构,它提供了快速和高效的查找、插入和删除操作。它的底层哈希表实现非常高效,并使用链地址法来处理哈希冲突。HashSet 非常适合需要存储唯一元素并快速检索它们的应用程序。

目录
相关文章
|
30天前
|
Java
【Java集合类面试二十八】、说一说TreeSet和HashSet的区别
HashSet基于哈希表实现,无序且可以有一个null元素;TreeSet基于红黑树实现,支持排序,不允许null元素。
|
1月前
|
存储 算法 Java
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
37 2
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
|
28天前
|
存储 安全 Java
Java 中 ArrayList 和 HashSet 的区别
【8月更文挑战第23天】
34 2
|
30天前
|
存储 Java
【Java集合类面试二十九】、说一说HashSet的底层结构
HashSet的底层结构是基于HashMap实现的,使用一个初始容量为16和负载因子为0.75的HashMap,其中HashSet元素作为HashMap的key,而value是一个静态的PRESENT对象。
|
3月前
|
存储 缓存 算法
滚雪球学Java(62):HashSet的底层实现原理解析
【6月更文挑战第16天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
32 3
滚雪球学Java(62):HashSet的底层实现原理解析
|
2月前
|
存储 安全 Java
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
|
3月前
|
存储 Java
打破常规!HashSet和TreeSet教你重新认识Java集合的无序与有序
【6月更文挑战第17天】Java集合框架中的Set接口,HashSet无序而TreeSet有序。HashSet基于哈希表,元素插入顺序不可预测,适合快速去重。TreeSet利用红黑树保证有序性,支持自然排序或自定义排序。若需同时无序和有序,可先用HashSet去重,再将元素加入TreeSet,但会牺牲性能。选择时依据对顺序和性能的需求。
100 2
|
3月前
|
算法 Java 数据处理
从HashSet到TreeSet,一场Java集合的“不重复”革命!
【6月更文挑战第17天】Java集合框架中的Set接口确保元素唯一,HashSet基于哈希表实现高效查找,不保证顺序;TreeSet使用红黑树保持排序,适用于有序场景。示例展示了HashSet的无重复添加及TreeSet的升序排列。Set是处理唯一性数据的利器。
23 0
|
4月前
|
安全 Java
Java HashSet
5月更文挑战第13天
|
4月前
|
存储 安全 Java
Java一分钟之-集合框架进阶:Set接口与HashSet
【5月更文挑战第10天】本文介绍了Java集合框架中的`Set`接口和`HashSet`类。`Set`接口继承自`Collection`,特征是不允许重复元素,顺序不确定。`HashSet`是`Set`的实现,基于哈希表,提供快速添加、删除和查找操作,但无序且非线程安全。文章讨论了`HashSet`的特性、常见问题(如元素比较规则、非唯一性和线程安全性)以及如何避免这些问题,并提供了代码示例展示基本操作和自定义对象的使用。理解这些概念和注意事项能提升代码效率和可维护性。
38 0