当前位置: 首页 > news >正文

【某大厂一面】HashSet底层怎么实现的

HashSet 是 Java 集合框架中的一个非常常用的集合类,它实现了 Set 接口,并且底层通常是通过 哈希表HashMap)来实现的。要理解 HashSet 的底层实现,我们需要从哈希表的工作原理开始讲起。下面是对 HashSet 底层实现的详细解析。

1. HashSet 的基本特性

  • 无重复元素HashSet 不允许存储重复的元素。如果向 HashSet 中添加一个已经存在的元素,插入操作会失败。
  • 不保证元素的顺序HashSet 不保证元素的顺序,它会根据元素的哈希值决定元素存储的顺序。
  • 支持 null 元素HashSet 允许存储一个 null 元素。

2. HashSet 底层实现原理

HashSet 实际上是基于 哈希表 实现的,而哈希表的实现是通过 HashMap 类来完成的。其基本结构和工作原理如下:

  • HashSet 使用了 HashMap 作为底层存储结构。
  • 每个 HashSet 中的元素都会作为 HashMapkey 存储,而 HashMapvalue 部分则始终使用一个固定的对象(通常是 Object)作为占位符。
哈希表(HashMap)工作原理:
  1. 哈希值计算:当元素被插入到 HashSet 中时,首先会计算该元素的哈希值(使用元素的 hashCode() 方法)。哈希值决定了元素应该存放在哈希表的哪个位置。
  2. 冲突处理:如果两个不同的元素有相同的哈希值(即哈希冲突),HashMap 会通过链表(在 Java 8 之后,也可能是红黑树)来处理这些冲突。链表或树结构会存储多个哈希值相同的元素。
  3. 键值存储:在 HashMap 中,每个 key 对应着一个值(value)。在 HashSet 中,value 部分是固定的,通常不关心具体的值。
HashSet 依赖 HashMap 的特点:
  • 插入操作时,HashSet 会调用 HashMap.put(key, value) 方法来将元素作为 key 存储。
  • 查找操作时,HashSet 会调用 HashMap.containsKey(key) 方法来判断该元素是否存在。
  • 删除操作时,HashSet 会调用 HashMap.remove(key) 方法来删除元素。

3. HashSet 的常用操作分析

1. 添加元素(add()

当调用 HashSetadd() 方法时,底层实际上调用的是 HashMapput() 方法:

  • 计算元素的哈希值。
  • 判断该元素是否已经存在于哈希表中(即是否有相同的哈希值且相等的元素)。
  • 如果元素不存在,插入元素并返回 true;如果元素已经存在,返回 false
public boolean add(E e) {return map.put(e, PRESENT) == null; // map.put() 返回值为 null 表示插入成功
}

HashSet 中,PRESENT 是一个常量,通常是 new Object()

2. 查找元素(contains()

查找操作会调用 HashMapcontainsKey() 方法:

  • 计算元素的哈希值。
  • 判断该哈希值对应的桶中是否存在元素。
  • 如果存在,进一步比较元素是否相等(使用 equals() 方法),如果相等返回 true,否则返回 false
public boolean contains(Object o) {return map.containsKey(o); // 调用 HashMap 的 containsKey()
}
3. 删除元素(remove()

删除操作会调用 HashMapremove() 方法:

  • 计算元素的哈希值。
  • 查找该元素并删除。
public boolean remove(Object o) {return map.remove(o) == PRESENT; // 调用 HashMap 的 remove() 删除元素
}
4. 获取集合大小(size()

返回 HashSet 中存储的元素数量,底层是通过 HashMapsize() 方法获取的:

public int size() {return map.size(); // 调用 HashMap 的 size() 获取大小
}

4. HashSetHashMap 的关系

  • HashSet 本质上是对 HashMap 的包装,HashSet 的元素会作为 HashMapkey 存储,而 value 部分固定不变。
  • HashMapkey 使用 hashCode()equals() 方法来判断元素是否相等,所以 HashSet 中的元素也必须重写 hashCode()equals() 方法。
  • HashSet 具有与 HashMap 相同的效率特性,所有常用操作(插入、查找、删除)的时间复杂度均为 O(1),但在最坏情况下(哈希冲突严重)为 O(n)。

5. HashSet 性能特点

由于 HashSet 底层是基于哈希表的,因此它在大多数情况下提供非常高效的性能:

  • 插入操作:O(1),在没有哈希冲突的情况下,插入一个元素是常数时间。
  • 查找操作:O(1),由于哈希表是基于哈希值查找元素,查找操作通常是常数时间。
  • 删除操作:O(1),与查找操作类似,删除操作也基于哈希值进行快速定位。
  • 最坏情况下:如果所有元素都发生哈希冲突(即所有元素都被分配到同一个桶中),则所有操作的时间复杂度会退化到 O(n)。

为了减少哈希冲突,HashSetHashMap 都采用了动态扩容和哈希重哈希机制。当哈希表的负载因子(实际存储的元素数与数组容量之比)超过某个阈值时,会进行扩容(通常会将数组大小扩展为原来的 2 倍),并重新计算所有元素的哈希值并重新分配到新的数组位置。

6. HashSet 的扩容机制

HashSet 会根据负载因子和容量来动态调整内部存储数组的大小。默认情况下,HashSet 的初始容量为 16,负载因子为 0.75。

  • 容量:是哈希表的数组大小。
  • 负载因子:是哈希表的填充程度,默认值为 0.75。当哈希表中存储的元素个数超过容量的 75% 时,哈希表会进行扩容。

扩容操作会导致重新计算所有元素的哈希值,因此在性能方面可能会有一定的开销。

7. 总结

特性HashSet
底层实现基于 HashMap
是否允许重复元素不允许
是否保证顺序不保证
存储元素的方式元素作为 HashMapkey 存储,value 固定
插入操作时间复杂度O(1),最坏情况 O(n)
查找操作时间复杂度O(1),最坏情况 O(n)
删除操作时间复杂度O(1),最坏情况 O(n)

HashSet 是一个高效的集合类,适用于需要去重、无序存储的场景。它的性能与哈希表的设计紧密相关,能够提供快速的插入、查找和删除操作。

小伙伴们在开发过程中有使用心得可以再评论区一块讨论哦

相关文章:

【某大厂一面】HashSet底层怎么实现的

HashSet 是 Java 集合框架中的一个非常常用的集合类,它实现了 Set 接口,并且底层通常是通过 哈希表(HashMap)来实现的。要理解 HashSet 的底层实现,我们需要从哈希表的工作原理开始讲起。下面是对 HashSet 底层实现的详…...

动手学图神经网络(3):利用图神经网络进行节点分类 从理论到实践

利用图神经网络进行节点分类:从理论到实践 前言 在之前的学习中,大家对图神经网络有了初步的了解。本次教程将深入探讨如何运用图神经网络(GNNs)来解决节点分类问题。在节点分类任务里,大家往往仅掌握少量节点的真实标签,却要推断出其余所有节点的标签,这属于归纳式学…...

免杀国内主流杀软的恶意样本分析

目录下存在愤怒的小鸟.exe和fun.dll文件,最新版火绒,windows defender,腾讯电脑管家,360静态扫描都未发现恶意程序 动态执行,杀软也未拦截 上传到virustotal网站分析恶意程序,只有三个引擎检测出来 die分析…...

第4章 基于中点电流的NPC逆变器中点电压平衡策略

1. 工作原理 1.1 NPC型三电平逆变器工作原理 NPC型三相三电平逆变器有A、B、C三个桥臂,其组成结构是相同的,本章以A相为例,对其工作原理进行分析。开关器件SA1和SA3、SA2和SA4为互补器件,通过控制开关器件的导通和关断状态&#…...

消息队列篇--通信协议篇--应用层协议和传输层协议理解

在网络通信中,传输层协议和应用层协议是OSI模型中的两个不同层次的协议,它们各自承担着不同的职责。 下文中,我们以TCP/UDP(传输层协议)和HTTP/SMTP(应用层协议)为例进行详细解释。 1、传输层协…...

FLTK - FLTK1.4.1 - demo - animgifimage

文章目录 FLTK - FLTK1.4.1 - demo - animgifimage概述笔记END FLTK - FLTK1.4.1 - demo - animgifimage 概述 知识点: 注册图像文件类型判断回调 FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg 事件回调的注册 GIF图像显示为图片或动画的标志设置 // 超时回调的设置…...

目前市场主流的AI PC对于大模型本地部署的支持情况分析-Deepseek

以下是目前市场主流AI PC对**大模型本地部署支持情况**的综合分析,结合硬件能力、软件生态及厂商动态进行总结: --- ### **一、硬件配置与算力支持** 1. **核心处理器架构** - **异构计算方案(CPUGPUNPU)**:主流…...

1.2 基于深度学习的底层视觉技术

文章目录 高层视觉任务与底层视觉任务深度神经网络相对于传统方法的优势 高层视觉任务与底层视觉任务 计算机视觉中的任务包含高层视觉任务,底层视觉任务。高层视觉任务是处理语义级别相关的任务,例如图像分类、目标检测、图像分割等。底层视觉任务处理与…...

HTML 标题

HTML 标题 引言 HTML(超文本标记语言)是构建网页的基础,而标题则是网页中不可或缺的元素。标题不仅能够帮助用户快速了解网页内容,还能够对搜索引擎优化(SEO)产生重要影响。本文将详细介绍HTML标题的用法…...

SOME/IP--协议英文原文讲解3

前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 Note: Thi…...

Microsoft Visual Studio 2022 主题修改(补充)

Microsoft Visual Studio 2022 透明背景修改这方面已经有很多佬介绍过了,今天闲来无事就补充几点细节。 具体的修改可以参考:Microsoft Visual Studio 2022 透明背景修改(快捷方法)_material studio怎么把背景弄成透明-CSDN博客文…...

UE(UltraEdit) 配置简易C/C++编译运行环境

该类型其他帖子 EmEditor 配置简易C/C 编译运行环境_emeditor 代码运行-CSDN博客 RJ TextEd 配置简易C/C 编译运行环境-CSDN博客 这种配置适合ACM竞赛,即要求不使用现代IDE,又想用一个比较好用、至少支持代码高亮的编辑器。 前提条件 1.Mingw GCC 已…...

使用 MSYS2 qemu 尝鲜Arm64架构国产Linux系统

近期,我的师弟咨询我关于Arm64架构的国产CPU国产OS开发工具链问题。他们公司因为接手了一个国企的单子,需要在这类环境下开发程序。说实在的我也没有用过这个平台,但是基于常识,推测只要基于C和Qt,应该问题不大。 1. …...

python Flask-Redis 连接远程redis

当使用Flask-Redis连接远程Redis时,首先需要安装Flask-Redis库。可以通过以下命令进行安装: pip install Flask-Redis然后,你可以使用以下示例代码连接远程Redis: from flask import Flask from flask_redis import FlaskRedisa…...

在Windows系统中本地部署属于自己的大语言模型(Ollama + open-webui + deepseek-r1)

文章目录 1 在Windows系统中安装Ollama,并成功启动;2 非docker方式安装open-webui3下载并部署模型deepseek-r1 Ollama Ollama 是一个命令行工具,用于管理和运行机器学习模型。它简化了模型的下载与部署,支持跨平台使用&#xff0c…...

Haproxy入门学习二

一、Haproxy的算法 1.haproxy通过固定参数balance指明对后端服务器的调度算法,其中balance参数可以配置在listen或backend选项中 2.haproxy的调度算法分为静态和动态调度算法,其中有些算法可以根据参数在静态和动态算法中相互转换 3.静态算法&#xff1a…...

Git图形化工具【lazygit】

简要介绍一下偶然发现的Git图形化工具——「lazygit」 概述 Lazygit 是一个用 Go 语言编写的 Git 命令行界面(TUI)工具,它让 Git 操作变得更加直观和高效。 Github地址:https://github.com/jesseduffield/lazygit 主要特点 主要…...

node 爬虫开发内存处理 zp_stoken 作为案例分析

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 前言 主要说3种我们补环境过后如果用…...

基于Langchain-Chatchat + ChatGLM 本地部署知识库

一、相关环境 参考链接: Github:https://github.com/chatchat-space/Langchain-Chatchat Langchain-chatchat版本:v0.3.1 安装环境:Ubuntu:22.04,CUDA:12.1 二、搭建过程 2.1 环境配置 2.1.1 创建chatchat虚拟环…...

【C语言】main函数解析

一、前言 在学习编程的过程中,我们很早就接触到了main函数。在Linux系统中,当你运行一个可执行文件(例如 ./a.out)时,如果需要传入参数,就需要了解main函数的用法。本文将详细解析main函数的参数&#xff…...

Hermes Agent:引爆企业AI革命!自进化智能体协作实战与落地指南

Hermes Agent 是一款自进化AI代理系统,具备完整学习循环、跨会话记忆、用户建模等核心特性。本文深入解析其架构、多智能体协作机制及自进化能力,并通过智能客服、DevOps自动化、数据分析等企业级案例,展示如何构建高效AI代理系统。同时提供性…...

深度强化学习在航天控制中的仿真到实物迁移挑战

1. 深度强化学习在航天控制领域的应用背景卫星近距离操作是航天任务中的一项关键技术挑战,涉及轨道交会、在轨服务、空间目标检测等多种场景。传统基于模型预测控制(MPC)的方法需要精确的环境动力学模型,而实际太空环境中存在诸多…...

Linux端口转发到外网完全教程:iptables DNAT+SNAT实现内网服务暴露

一、什么是外网端口转发Linux端口转发到外网,是指将Linux服务器上某个端口的流量,转发到外网(公网)的另一台服务器。这样做的典型场景是:你有一台内网服务器没有公网IP,但另一台海外服务器有公网IP&#xf…...

DevOps 与 CI/CD 实战心得:静态网站的自动化部署

背景 自己做了一个独立站项目,访问地址是:https://www.wslwf.com 通过这次实践,对 DevOps 和 CI/CD 在静态网站场景中的应用有了更深的理解。 核心体会 1. 工具链选择至关重要 这次项目使用了 GitHub Actions GitHub Pages,这个组…...

从ENVI SARscape到SNAP:手把手教你迁移哨兵1 GRD数据预处理流程(含避坑指南)

从ENVI SARscape到SNAP:哨兵1 GRD数据预处理全流程迁移实战 当雷达遥感领域的工具生态逐渐向开源化倾斜,许多长期依赖ENVI SARscape的研究者开始面临工具迁移的挑战。本文将聚焦哨兵1号GRD数据的预处理流程,为需要从商业软件转向开源工具的用…...

在新磁盘挂载点/data安装codex

实例是 Oracle Cloud Always Free VM.Standard.E2.1.Micro Linux, /data 目录。 Codex CLI 官方支持用 npm 安装:npm i -g openai/codex,首次运行需要登录 ChatGPT 或配置 API key; 建议:Codex 安装到 /data;bubblewr…...

共筑智能传播信息安全域,新华社国家重点实验室与北京时光不语达成合作

新华社媒体融合生产技术与系统国家重点实验室与北京时光不语科技有限公司(TIMUS.AI)正式建立研发生态伙伴关系,并联合推出面向智能传播环境的“新华智信感知平台”,深化智能传播领域科研创新与成果转化,共同构建负责任…...

数据分析实习面试准备全攻略:专业知识+项目深挖+行为面试,职卓科技的面试辅导体系

摘要数据分析实习面试通常包含三大模块:专业知识考察(SQL、Python、统计学基础)、项目深挖(业务理解、技术选择、问题解决)、行为面试(团队协作、学习能力、职业规划)。很多学员在面试中表现不佳…...

使用Taotoken后如何清晰观测API用量与成本变化

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Taotoken后如何清晰观测API用量与成本变化 对于团队管理者或开发者而言,将大模型能力集成到产品中后,资…...

LyricsX:一站式macOS歌词同步解决方案,让音乐体验更智能

LyricsX:一站式macOS歌词同步解决方案,让音乐体验更智能 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX LyricsX是macOS平台上功能最全面的歌词同步工具&#xff…...