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

对 equals() 和 hashCode() 的理解?

在 java.lang.Object 类中有两个非常重要的方法:

public native int hashCode();
public boolean equals(Object obj) {return (this == obj);
}

Object 类是类继承结构的基础,是每一个类的父类,都实现了Object 类中定义的方法。

equals()方法:

equals()方法是用作对象之间进行比较的,判断是否相等。
在 Object 类中 equals() 方法是 == 对两个对象之间的地址值进行的比较(引用是否相同)。
String 封装类中在使用 equals() 方法时,已经重写了父类 Object 的 equals() 方法。

public boolean equals(Object anObject) {// 查看地址值是否相同,是否为同一引用if (this == anObject) {return true;}// 是否是String 类型if (anObject instanceof String) {// 强转为 String 类型String anotherString = (String)anObject;int n = value.length;// 内容比较if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;
}

equals() 方法拥有的特性:
x 和 y 都不为 null

  1. 自反性:x.equals(x) 一定为 true
  2. 一致性:如果 x,y 的信息没有被修改过,x.equals(y) 被多次调用也会返回相同的值
  3. 对称性:x.equals(y) = true 则 y.equals(x) = true
  4. 传递性:x.equals(y) = true ,y.equals(z) = true 则 x.equals(z) 一定为 true
  5. 对于 x.equals(null) 一定返回 false

当 equals() 方法被重写的时候,hashCode() 方法一定要重写,因为两个相同对象的 hashCode 一定相同。

hashCode()方法:

hashCode() 方法给对象返回一个 hashCode 值。这个方法被用于 hash tables,例如 HashMap

hashCode() 方法拥有的性质:

  1. 在一个Java程序运行期间,如果一个对象提供给 equals() 作比较的信息没有变化的话,该对象多次调用 hashCode() 方法,返回的应该是同一个Integer。
  2. 如果两个对象的 equals() 结果是 true。则两个对象的 hashCode 值一定相同。
  3. 并不是两个不相同的对象返回的 hashCode 值一定不同。

在String中定义的hashCode()方法:

public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h;}return h;
}

在Java中有两种集合(List 和 Set),List 有序可重复的,Set 无序不可重复的。

Set中要想保证数据不重复,根据什么来判断?

如果每增加一个元素都要进行 equals() 比较一次,当添加元素数据足够多(x)的时候,新增一个元素需要比较的次数就会为x次,需要调用x次 equals() 方法,这样性能就会特别低。于是Java采用了哈希表的原理(Hash算法,也称之为散列算法),是将数据依照特定的算法指定到一个地址上。这样每次新增数据的时候只需要调用 hashCode() 方法就能定位到存储的位置,如果这个位置上没有元素就可以直接存储,如果这个位置上有值则只需要调用一次 equals() 方法比较两个元素是否相同,相同的话覆盖,不相同的话重新散列到其他位置。这样就大大降低了 equals() 的比较次数了
简而言之:相同的对象,他们的HashCode 一定相同。两个对象的 HashCode 值相同,他们不一定相等

示例:

// 创建一个Person类,实现 getter/setter方法,以及toString 方法
@AllArgsConstructor
public class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}// 测试类
public class TestDemo {public static void main(String[] args) {HashSet<Person> hashSet = new HashSet<>();hashSet.add(new Person("zhangsan",18));hashSet.add(new Person("zhangsan",18));hashSet.add(new Person("zhangsan",18));System.out.println("hashSet = " + hashSet);}
}// 输出结果
hashSet = [Person{name='zhangsan', age=18}, Person{name='zhangsan', age=18}, Person{name='zhangsan', age=18}

当 Person 类没有重写 equals 和 hashCode 方法时,加入到HashSet中,每个对象生成的hashCode值都不相同,所以没办法判断重复

@AllArgsConstructor
public class Person {private String name;private int age;// getter/setter,toString方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
// 调用测试类
public class TestDemo {public static void main(String[] args) {HashSet<Person> hashSet = new HashSet<>();hashSet.add(new Person("zhangsan",18));hashSet.add(new Person("zhangsan",18));hashSet.add(new Person("zhangsan",18));System.out.println("hashSet = " + hashSet);}
}
// 输出结果
hashSet = [Person{name='zhangsan', age=18}]

相关文章:

对 equals() 和 hashCode() 的理解?

在 java.lang.Object 类中有两个非常重要的方法&#xff1a; public native int hashCode(); public boolean equals(Object obj) {return (this obj); }Object 类是类继承结构的基础&#xff0c;是每一个类的父类&#xff0c;都实现了Object 类中定义的方法。 equals()方法…...

IDEA插件安装慢、超时、不成功问题如何解决?

目录 一、打开国内插件的节点IP地址 二、修改本地hosts文件 三、刷新DNS缓存 一、打开国内插件的节点IP地址 国内插件的节点IP地址查询: http://tool.chinaz.com/speedtest/plugins.jetbrains.com 在下方的检测结果中&#xff0c;找到一个解析时间最短的IP地址&#xff0c;解…...

软考高级之信息系统案例分析七重奏-《5》

五十、项目需求管理可能存在的问题。 1、未制定项目需求管理计划; 2、项目沟通存在问题; 3、项目经理缺乏必要的项目管理经验; 4、没有有效地管理需求变更控制; 5、没有有效地维护对需求进行跟踪管理; 6、没有按照规范的需求开发和需求管理的内容和流程开展需求工作…...

JUC并发编程 Ⅳ -- 共享模型之无锁

文章目录CAS 与 volatile问题引入代码分析volatile为什么无锁效率高CAS特点原子整数原子引用ABA 问题及解决原子数组原子(字段)更新器原子累加器UnsafeUnsafe CAS 操作管程即 monitor 是阻塞式的悲观锁实现并发控制&#xff0c;本文我们将通过非阻塞式的乐观锁的来实现并发控制…...

Spring之AOP实现

1. AOP的实现方式 使用AspectJ的编译器来改动class类文件实现增强(使用不广泛) ----- 编译阶段 这种对class类文件增强的, 也可以增强static静态方法, 而通过代理方式就无法实现静态方法的增强 可通过查看编译后class文件反编译后的java代码验证 agent增强(使用不广泛) ----- 类…...

Spring之基于xml的自动装配、基于Autowired注解的自动装配

文章目录基于xml的自动装配①注解②扫描③新建Maven Module④创建Spring配置文件⑤标识组件的常用注解⑥创建组件⑦扫描组件⑧测试⑨组件所对应的bean的id基于注解的自动装配①场景模拟②Autowired注解③Autowired注解其他细节④Autowired工作流程Autowire 注解的原理Qualifier…...

【案例】--(非分布式)轻量级任务调度平台

目录 一、前言说明二、背景2.1、完成任务,顺便搭建了一个任务调度平台三、具体实现解析3.1、技术栈等选型3.2、完成具体功能解析(1)、支持基本任务功能(2)、支持日志收集功能(3)、支持用户异常,选择性关闭调度功能(4)、实时监控正在执行和任务队列的任务情况(5)、实时监控任务…...

key的作用原理与列表的遍历、追加、搜索、排序

目录 一、key的作用原理 二、实现列表遍历并对在列表最前方进行追加元素 三、实现列表过滤搜索 1、用computed计算属性来实现 2、用watch监听输入值的变化来实现 四、按年龄排序输出列表 一、key的作用原理 1. 虚拟DOM中key的作用&#xff1a; key是虚拟DOM对象的标识&a…...

SQL性能优化的47个小技巧,你了解多少?

收录于热门专栏Java基础教程系列&#xff08;进阶篇&#xff09; 1、先了解MySQL的执行过程 了解了MySQL的执行过程&#xff0c;我们才知道如何进行sql优化。 客户端发送一条查询语句到服务器&#xff1b;服务器先查询缓存&#xff0c;如果命中缓存&#xff0c;则立即返回存…...

DPDK — 数据加速方案的核心思想

目录 文章目录 目录DPDK 数据加速方案1、使用用户态协议栈来代替内核协议栈Linux UIO FrameworkDPDK UIO Framework2、使用轮训来代替中断Kernelspace igb_uio DriverUserspace PMD3、使用多核编程代替多线程无锁环队列:CPU 核间无锁通信DPDK 数据加速方案...

[python入门㊽] - 自定义异常 raise 关键字

目录 ❤ 自定义抛出异常关键字 - raise ❤ 使用raise主动引发异常 ❤ raise 关键字的用法 ❤ 触发异常 ❤ 自定义异常类 在前面我们学过异常三个关键字分别是try、except 以及 finally 在编程过程中合理的使用异常可以使得程序正常的执行。有直接抛出异常的形式&…...

DDOS攻击

注&#xff1a;本博客只是为了自己的学习&#xff0c;记录自己的学习&#xff0c;请勿用于其他途径、1、winR-->cmd2、ping 网站3、替换IP1 import java.io.BufferedInputStream;2 import java.io.IOException;3 import java.net.MalformedURLException;4 import java.net.U…...

网络编程套接字

文章目录1. socket编程接口1-1 socket 常见API1-2 sockaddr结构2. 简单的UDP网络程序2-1 日志&#xff08;固定用法&#xff1a;标准部分自定义部分&#xff09;2-2 服务器代码实现1. 框架2. 初始化服务器3. 服务器运行4. 调用服务器封装函数&#xff08;UdpServer&#xff09;…...

海量数据相似数据查询方法

1、海量文本常见 海量文本场景&#xff0c;如何寻找一个doc的topn相似doc&#xff0c;一般存在2个问题&#xff0c; 1)、两两对比时间o(n^2) 2)、高维向量比较比较耗时。 文本集可以看成(doc,word)稀疏矩阵&#xff0c;一般常见的方法是构建到排索引&#xff0c;然后进行归并…...

Codeforces Round #822 (Div. 2)

A(签到) - Select Three Sticks 题意&#xff1a; 给你一个长度为 n 的正整数序列&#xff0c;你可以操作任意次&#xff0c;每一次操作可以选择任意一个元素&#xff0c;把它 1 或者 - 1&#xff0c;问最少多少次操作可以使得序列中存在三个相同的数字以构成一个等边三角形.…...

华为OD机试 - 最短木板长度(JS)

最短木板长度 题目 小明有 n n n块木板,第 i i i(1≤ i i </...

java设计模式——观察者模式

概述 定义:又被称为发布-订阅(Publish/Subscribe)模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所有的观察者对象&#xff0c;使他们能够自动更新自己。 结构 在观察者模式…...

linux高级命令之线程的注意点

线程的注意点学习目标能够说出线程的注意点1. 线程的注意点介绍线程之间执行是无序的主线程会等待所有的子线程执行结束再结束线程之间共享全局变量线程之间共享全局变量数据出现错误问题2. 线程之间执行是无序的import threading import timedeftask():time.sleep(1)print(&qu…...

MyBatisPlus ---- 多数据源

MyBatisPlus ---- 多数据源1. 创建数据库及表2. 引入依赖3. 配置多数据源4. 创建用户service5. 创建商品service6. 测试适用于多种场景&#xff1a;纯粹多库、读写分离、一主多从、混合模式等 目前我们就来模拟一个纯粹多库的一个场景&#xff0c;其他场景类似 场景说明&#x…...

Java多线程

目录1 多线程1.1 进程1.2 线程1.3 多线程的实现方式1.3.1 方式1&#xff1a;继承Tread类1.3.2 方式2&#xff1a;实现Runnable接口1.3.3 方式3&#xff1a;实现Callable接口1.4 设置和获取线程名称1.5 线程调度1.6 线程控制1.7 线程生命周期1.8 数据安全问题之案例&#xff1a;…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...