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

HashSet中hashCode 与 equals 的关系?

hashCode 方法:返回对象的哈希码(一个整数)。hashCode 方法用于在哈希表中确定对象的存储位置。当向 HashSet 添加一个新对象时,Java 会先调用该对象的 hashCode 方法来计算出哈希码,用来定位对象在哈希表中的存储桶(bucket)。

equals 方法:用于判断两个对象是否在逻辑上相等。当两个对象的哈希码相同(即它们可能在同一个存储桶中),Java 会进一步使用 equals 方法来检查这些对象是否真的是相等的。

hashCode 与 equals 的规则

为了保证 HashSet 正常工作,必须遵循以下规则:

  1. 相等的对象必须有相同的哈希码:如果两个对象通过 equals 方法比较是相等的,那么它们的 hashCode 方法必须返回相同的整数值。这是为了保证当对象被放入 HashSet 时,它们被放在同一个存储桶中。

  2. 不相等的对象可以有相同的哈希码:两个对象即使 hashCode 相同,也不意味着它们是相等的;这只是意味着它们可能会被放在同一个存储桶中。此时,HashSet 会使用 equals 方法进一步检查它们是否相等。

举例说明

假设我们有一个简单的类 Person,根据它的 id 和 name 来判断两个对象是否相等。

class Person {private int id;private String name;public Person(int id, String name) {this.id = id;this.name = name;}// 重写 hashCode 方法@Overridepublic int hashCode() {return id; // 根据id生成哈希码}// 重写 equals 方法@Overridepublic boolean equals(Object obj) {if (this == obj) return true; // 如果是同一个对象,返回trueif (obj == null || getClass() != obj.getClass()) return false;Person person = (Person) obj;return id == person.id && name.equals(person.name); // 根据id和name判断是否相等}@Overridepublic String toString() {return "Person{id=" + id + ", name='" + name + "'}";}
}

使用 HashSet 的例子:

import java.util.HashSet;public class Main {public static void main(String[] args) {HashSet<Person> people = new HashSet<>();Person p1 = new Person(1, "Alice");Person p2 = new Person(1, "Alice"); // 同样的id和namePerson p3 = new Person(2, "Bob");people.add(p1);people.add(p2); // p2 和 p1 相等,HashSet 中不应该有重复people.add(p3);System.out.println(people); // 输出:[Person{id=1, name='Alice'}, Person{id=2, name='Bob'}]}
}

在这个例子中:

  • p1 和 p2 有相同的 id 和 name。因此,它们的 hashCode 相同(都是1),并且 equals 方法返回 true,表示它们是相等的对象。
  • 当我们将 p2 添加到 HashSet 时,HashSet 先计算它的哈希码(1),发现 p1 的哈希码也是1,于是进一步使用 equals 方法进行比较,结果为 true。因此,HashSet 认为 p2 是重复的对象,不会将它添加进去。
  • p3 的 id 不同(2),所以 hashCode 也不同。当 p3 被添加到 HashSet 时,HashSet 直接将其插入,因为没有找到哈希码相同的对象。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • <Rust>egui学习之小部件(三):如何为窗口UI元件设置布局(间隔、水平、垂直排列)?
  • python基础学习(最终篇)
  • 内存管理篇-17解开页表的神秘面纱-上
  • 定时器方案:时间表盘
  • Python实现蜂窝六边形的实现方法
  • 素材无水印素材网站在哪下载?高清的无水印素材资源库分享
  • AcWing 902. 最短编辑距离
  • VS Code 安装文档
  • MediaGo下载器:专业级功能,轻松应对各种下载需求!
  • 【Qt笔记】QTreeView控件详解
  • 独孤思维:打工,被老板压榨怎么办?
  • AWTK fscript 中的字符串扩展函数
  • CString类的用法以及例子
  • Java_ElasticSearch(ES)——分布式搜索引擎
  • jmeter 响应乱码
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • JAVA_NIO系列——Channel和Buffer详解
  • Mac转Windows的拯救指南
  • Python_网络编程
  • redis学习笔记(三):列表、集合、有序集合
  • Shadow DOM 内部构造及如何构建独立组件
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 思维导图—你不知道的JavaScript中卷
  • 译自由幺半群
  • 用mpvue开发微信小程序
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 1.Ext JS 建立web开发工程
  • 阿里云ACE认证之理解CDN技术
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • ## 基础知识
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ros//EnvironmentVariables)ros环境变量
  • (二)c52学习之旅-简单了解单片机
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (黑马C++)L06 重载与继承
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (转)shell调试方法
  • .NET Core中如何集成RabbitMQ
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET的微型Web框架 Nancy
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET中使用Redis (二)
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @javax.ws.rs Webservice注解
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [2024-06]-[大模型]-[Ollama] 0-相关命令
  • [BT]BUUCTF刷题第9天(3.27)
  • [dfs] 图案计数
  • [EFI]Acer Aspire A515-54g电脑 Hackintosh 黑苹果efi引导文件
  • [HNOI2018]排列
  • [JS]JavaScript 简介
  • [js高手之路] dom常用API【appendChild,insertBefore,removeChild,replaceChild,cloneNode】详解与应用...