Java 中 Set 集合是如何实现添加元素保证不重复的?

Java 中的 Set 集合是一种不允许包含重复元素的集合。它主要通过两种方式来实现确保元素不重复的机制:一是依赖元素的 hashCode() 方法和 equals() 方法,二是底层数据结构的支持。

1. hashCode() 和 equals() 方法

在 Java 中,每个对象都有一个 hashCode() 方法,用于返回对象的哈希码值,而 equals() 方法用于比较两个对象是否相等。Set 集合通过这两个方法来确保元素的唯一性。

hashCode() 方法

hashCode() 方法返回的是对象的哈希码值,它是一个 int 类型的整数。哈希码值可以视作对象的“身份证”,用于快速确定对象在集合中的存储位置。在 HashSet、LinkedHashSet 和 TreeSet 这些 Set 的实现中,都会用到 hashCode() 方法来决定元素在底层数据结构中的存储位置。

在默认情况下,Object 类中的 hashCode() 方法是根据对象的内存地址计算的,每个对象的哈希码值都是独一无二的。但是,为了确保 Set 集合中的元素唯一性,我们通常会重写 hashCode() 方法,使得相等的对象具有相等的哈希码值。

equals() 方法

equals() 方法用于比较两个对象是否相等。在 Set 集合中,当两个对象的 equals() 方法返回 true 时,这两个对象被认为是相等的,因此 Set 集合中不会包含重复的元素。

在实现自定义类时,我们通常也会重写 equals() 方法,以便正确地比较对象的内容而不是引用。在重写 equals() 方法时,需要遵循以下约定:

  • 自反性:对于任意非 null 的引用值 x,x.equals(x) 应该返回 true。
  • 对称性:对于任意非 null 的引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 应该返回 true。
  • 传递性:对于任意非 null 的引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 也返回 true,那么 x.equals(z) 应该返回 true。
  • 一致性:对于任意非 null 的引用值 x 和 y,只要 equals() 比较的信息没有被修改,那么多次调用 x.equals(y) 应该一致地返回 true 或 false。
  • 对于任意非 null 的引用值 x,x.equals(null) 应该返回 false。

通过重写 equals() 方法,我们可以自定义对象之间的相等性判断逻辑,从而确保 Set 集合中的元素不会重复。

2. 底层数据结构的支持

Java 中的 Set 集合有多种实现,如 HashSet、LinkedHashSet 和 TreeSet,它们都采用了不同的底层数据结构来实现元素的唯一性。

HashSet

HashSet 是基于哈希表(Hash Table)实现的,它利用了哈希码值来快速定位元素。当向 HashSet 中添加元素时,HashSet 首先会计算元素的哈希码值,然后根据哈希码值找到元素在哈希表中的存储位置,如果该位置为空,则将元素插入其中;如果该位置已经存在其他元素,则通过 equals() 方法来判断是否重复,如果重复则不进行插入操作。

HashSet 的插入、删除和查找操作的时间复杂度都是 O(1),因此它是一种高效的数据结构。但是,由于 HashSet 是基于哈希表实现的,它不保证元素的顺序,因此不适用于有序集合的场景。

LinkedHashSet

LinkedHashSet 是 HashSet 的一个子类,它除了具有 HashSet 的特性外,还保留了元素的插入顺序。LinkedHashSet 内部维护了一个双向链表,用于维护元素的插入顺序。因此,当遍历 LinkedHashSet 时,元素的顺序与插入顺序一致。

LinkedHashSet 的性能与 HashSet 类似,插入、删除和查找操作的时间复杂度都是 O(1),但是它会占用更多的内存空间来维护插入顺序。

TreeSet

TreeSet 是基于红黑树(Red-Black Tree)实现的,它能够保持元素的自然顺序或者根据比较器来排序。当向 TreeSet 中添加元素时,TreeSet 会根据元素的比较结果来确定元素的存储位置,如果该位置已经存在其他元素,则通过比较器或者自然顺序来判断是否重复,如果重复则不进行插入操作。

TreeSet 的插入、删除和查找操作的时间复杂度都是 O(log n),其中 n 是集合中元素的个数。由于 TreeSet 是基于红黑树实现的,它能够保持元素的有序性,因此适用于需要有序集合的场景。

3. 示例代码

下面是一个简单的示例代码,演示了如何使用 HashSet 来确保元素不重复:

import java.util.HashSet;
import java.util.Set;public class Main {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素set.add("apple");set.add("banana");set.add("apple"); // 重复元素,不会被添加// 遍历元素for (String element : set) {System.out.println(element);}}
}

在上面的代码中,我们创建了一个 HashSet 对象,并向其中添加了三个元素。由于第一个元素和第三个元素相同,因此第三个元素不会被添加到集合中。最后,我们通过 for-each 循环遍历集合中的元素,并将其打印出来。

通过重写 hashCode() 和 equals() 方法,并采用不同的底层数据结构来实现,Java 中的 Set 集合能够高效地确保元素不重复。HashSet 基于哈希表实现,保证了插入、删除和查找操作的高效性;LinkedHashSet 在 HashSet 的基础上增加了对元素插入顺序的保留;TreeSet 基于红黑树实现,能够保持元素的有序性。开发者可以根据实际需求选择合适的 Set 实现,以满足不同场景下的需求。

黑马程序员免费预约咨询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【服务器配置】docker环境配置

docker环境配置 本文是在ubuntu 22.04机器配置docker环境 查看系统的内核版本 uname -a Linux xxf-ThinkStation-P340 5.15.0-101-generic #111-Ubuntu SMP Tue Mar 5 20:16:58 UTC 2024 x86_64 x86_64 x86_64 GNU/Linuxx86 64位 系统 如果是32位 不能安装docker 更新软件…

分布式数据库Polardb-X架构及特点

PolarDB-X架构 计算节点&#xff08;Compute Node&#xff0c;CN&#xff09;是系统的入口&#xff0c;采用无状态设计的sql引擎提供分布式路由和计算&#xff0c;包括SQL解析器、优化器、执行器等模块。负责数据分布式路由、计算及动态调度&#xff0c;负责分布式事务2PC协调…

基于java+springboot+vue实现的学生信息管理系统(文末源码+Lw+ppt)23-54

摘 要 人类现已进入21世纪&#xff0c;科技日新月异&#xff0c;经济、信息等方面都取得了长足的进步&#xff0c;特别是信息网络技术的飞速发展&#xff0c;对政治、经济、军事、文化等方面都产生了很大的影响。 利用计算机网络的便利&#xff0c;开发一套基于java的大学生…

文献学习-37-动态场景中任意形状针的单目 3D 位姿估计:一种高效的视觉学习和几何建模方法

On the Monocular 3D Pose Estimation for Arbitrary Shaped Needle in Dynamic Scenes: An Efficient Visual Learning and Geometry Modeling Approach Authors: Bin Li,† , Student Member, IEEE, Bo Lu,† , Member, IEEE, Hongbin Lin, Yaxiang Wang, Fangxun Zhong, Me…

PHP01——php快速入门 之 在Mac上使用phpstudy快速搭建PHP环境

PHP01——php快速入门 之 在Mac上使用phpstudy快速搭建PHP环境 0. 前言1. 下载小皮面板1.1 下载phpstudy&#xff08;小皮面板&#xff09;1.2 启动、简单访问1.2.1 启动Apache1.2.2 访问1.2.3 访问自定义文件或页面 2. 创建网站2.1 创建网站2.2 可能遇到的问题2.2.1 hosts权限…

Prompt提示工程上手指南:基础原理及实践-思维树 (ToT)策略下的Prompt

前言 此篇文章已经是本系列的第五篇文章&#xff0c;之前我们已经将检索增强生成(RAG)策略&#xff0c;逐渐我们掌握的知识和技术都在不断提高&#xff0c;对于Prompt的技巧策略也不能只局限于局部运用而要适应LLM大模型的整体框架去进行改进休整。较为主流的LLM模型框架设计基…

提升数据质量的三大要素:清洗prompt、数据溯源、数据增强(含Reviewer2和PeerRead)​

前言 我带队的整个大模型项目团队超过40人了&#xff0c;分六个项目组&#xff0c;每个项目组都是全职带兼职&#xff0c;且都会每周确定任务/目标/计划&#xff0c;然后各项目组各自做任务拆解&#xff0c;有时同组内任务多时 则2-4人一组 方便并行和讨论&#xff0c;每周文档…

Vue3实现pdf本地预览功能

一、先直接看看效果吧 放大后 缩小后 也可以分页显示 二、选用vue-pdf-embed和vue3-pdfjs的原因 选用这两个的插件是因为如果实现pdf预览其实使用iframe标签就可以的&#xff0c;但是使用iframe标签实现的比较臭&#xff0c;vue-pdf-embed是能够自定义样式的&#xff0c;更…

如何使用hugging face的模型库?

Hugging Face 是一个流行的自然语言处理 (NLP) 模型库和社区&#xff0c;提供了大量预训练模型、工具和资源&#xff0c;使得 NLP 的开发者和研究人员能够快速高效地构建和应用各种文本相关应用。在这里&#xff0c;我将向您介绍如何在 1 天内快速熟悉 Hugging Face 的基本功能…

分析系统性能问题从哪里入手?

本人十年大厂经验&#xff0c;整理技术资料不易&#xff0c; 完整详细文章关注公众号&#xff0c;后续还会有免费学习资料 1. 高性能架构的三个核心优化手段 负载均衡&#xff1a;通过分发用户请求到多个服务器&#xff0c;降低单一服务器的负载压力。 应用层负载均衡&#xf…

Python零基础从小白打怪升级中~~~~~~~TCP网络编程

TCP网络编程 一、什么是TCP协议 TCP( Transmission control protocol )即传输控制协议&#xff0c;是一种面向连接、可靠的数据传输协议&#xff0c;它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接 &#xff1a;数据传输之前客户端和…

Stable Diffusion AI绘画宝典:从新手到高手,一图胜千言!

在这个数字化时代的浪潮中&#xff0c;人工智能技术以其惊人的创造力和创新性席卷全球。党的二十大报告把“实施科教兴国战略&#xff0c;强化现代化建设人才支撑”作为战略举措进行系统阐述&#xff0c;彰显我国不断发展新动能、新优势的决心和气魄。 Stable Diffusion是一款…

Vue3 + Element-Plus 使用 Table 预览图片发生元素遮挡

Vue3 Element-Plus 使用 Table 预览图片发生元素遮挡 问题代码问题重现解决方法最终效果 问题代码 <el-table-column label"视频" align"center"><template #default"scope" style"display: flex;"><div style"…

碾压LoRA!Meta CMU | 提出高效大模型微调方法:GaLore,内存可减少63.3%

引言 大模型训练通常会遇到内存资源的限制。目前常用的内存减少方法低秩适应&#xff08;LoRA&#xff09;&#xff0c;通过引入低秩&#xff08;low-rank&#xff09;适配器来更新模型的权重&#xff0c;而不是直接更新整个权重矩阵。然而&#xff0c;这种方法在预训练和微调…

消息队列和分布式消息队列

文章目录 分析系统现状不足中间件消息队列什么是消息队列&#xff1f;应用场景消息队列的模型为什么不直接传输&#xff0c;而要用消息队列&#xff1f;为什么要用消息队列&#xff1f;消息队列的缺点&#xff1f; 分布式消息队列分布式消息队列的优势&#xff1f;消息队列应用…

LeetCode55题:跳跃游戏(原创)

【题目描述】 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&am…

Oracle 19c补丁升级(Windows)

文章目录 一、打补丁前备份检查1、补丁包获取2、备份数据包以及数据库软件3、检查OPatch版本 二、补丁升级1、更新OPatch2、关闭监听以及服务3、补丁升级过程4、启动监听以及服务 三、数据库补丁应用 一、打补丁前备份检查 1、补丁包获取 补丁包&#xff1a; 百度网盘链接&am…

甘特图使用小诀窍,项目把控游刃有余

在项目管理过程中,掌握甘特图的使用技巧可以让你事半功倍,高效规划和监控项目进度。作为一种视觉化的工具,甘特图直观地展示了任务的开始和结束时间、持续时间以及任务之间的依赖关系,有助于预测和优化资源分配。掌握以下几个小诀窍,你就能驾驭甘特图,游刃有余地把控整个项目。…

运营商三要素验证API接口怎么对接

运营商三要素验证API接口又叫手机三要素验证API接口、运营商实名认证接口&#xff0c;这个接口是验证姓名、身份证号、手机号三者是否一致&#xff0c;返回验证结果&#xff0c;如果一致则说明三者信息匹配&#xff0c;可以有效确认当前注册用户的身份信息&#xff0c;那么运营…

山姆·奥特曼是如何成为亿万富豪的?

2017年夏天&#xff0c;Superhuman公司首席执行官拉胡尔沃拉&#xff08;Rahul Vohra&#xff09;开始疯狂向投资者一一发消息&#xff0c;缘由是他的初创公司尝试了谷歌浏览器Chrome的一项即将推出的更新。由于一个看似无害的代码更改&#xff0c;Superhuman的智能电子邮件服务…