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

Java 中的 == 运算符、equals 方法和 hashcode 方法

一、== 运算符

== 是 Java 中的一个运算符,用于比较两个对象,但在比较两个对象的时候需要根据比较类型分情况进行讨论。

1.1 基本数据类型与基本数据类型

基本数据类型之间通过 == 进行比较的时候,是直接比较它们的大小,而与它们的具体类型无关。

short num1 = 20000;
int num2 = 20000;
System.out.println(num1 == num2); // Output: true

1.2 引用类型与引用类型

引用类型之间是比较它们的内存地址,因此两个同类型的对象通过 == 进行比较时的结果一般为 false。

public class Test {public static void main(String[] args) {Obj o1 = new Obj();Obj o2 = new Obj();System.out.println(o1 == o2); // Output: false}
}class Obj {}

但也不是所有情况都会返回 false,基本数据类型的引用类型有个常量池的机制,使得它们就算是两个对象,依然会指向同一片内存空间,也就是说,它们依然是同一个对象。

Integer num1 = 100, num2 = 100;
System.out.println(num1 == num2); // Output: true

具体内容请见:八大基本类型及其包装类型

1.3 基本数据类型与引用类型

当基本数据类型与引用类型之间进行比较时,若引用类型是数字类的,那么就可以进行比较,其他类型的无法进行比较,会报错。

Integer num1 = 200;
int num2 = 200;
System.out.println(num1 == num2); // Output: trueint num = 200;
String str = "123";
System.out.println(str == num); // Error: 二元运算符 '==' 的操作数类型错误

二、equals 方法

equals 是 Java 引用类型的一个基本方法,在没有对其进行重写(override)的情况下,equals 方法默认是比较两个对象的内存地址,重写之后视具体情况而定。

String str1 = "1";
String str2 = "2";
System.out.println(str1.equals(str2)); // Output: false

2.1 equals 方法和 == 运算符的区别

  • == 是一个运算符,equals 是对象的方法(所以基本数据类型没有);
  • == 在比较基本数据类型时,是比较的值,比较对象的时候,是比较其内存地址;
  • equals 默认(没有被重写)是比较对象的内存地址,重写后是其他的内容(如 String 就是其对象所表示内容的值)

三、hashcode 方法

hashcode 是一个非常特殊的方法,它涉及到散列表的知识,哈希(hash)翻译过来就是散列的意思,它是一种算法,可以快速将任意对象转换为一个 16 进制的数值,而不同的对象之间,通过哈希算法得到的哈希值大概率是不会相同的,有极小概率会相同,此时就出现了一种被称为“哈希冲突”的情况,这里我们不对其做深究,具体内容请参见:哈希算法

总之,在没有出现“哈希冲突”的情况下,我们就可以通过不同对象的哈希值不相同这一特性来判断两个对象是否为同一对象。

String str1 = "1";
String str2 = "2";
System.out.println(str1.hashCode() == str2.hashCode()); // Output: false

当然,一般情况下我们是不会像上面这样用 hashcode 这一方法的,因为无法保证不会出现“哈希冲突”的情况。虽然不同对象的哈希值有可能相同,但是两个对象的哈希值的不同则说明它们一定不相同!因此,哈希值可以用于判断两个对象是否不等。

四、区别和联系

4.1 区别

== 一般用来判断数字是否相等,equals 一般用来判断两个对象是否相等,而 hashcode 一般用来判断两个对象是否不等。

== 只比较数字,判断速度最快,此外是 hashcode 方法,因为哈希值的计算十分快速,最后是 equals,默认情况下 equals 是比较两个对象的内存地址,这一过程虽然很快速,但更一般的情况是 equals 方法被重写了,比较的是两个非数字类型对象的属性值,因此它最慢。

String str1 = "1";
String str2 = "1";
System.out.println(str1.equals(str2)); // Output: true

上面的代码中,Java 内置引用类型 String 就重写了 equals 方法,它比较的是两个 String 对象的内容,而非内存地址。

4.2 联系

== 一般和 equals 和 hashcode 扯不上什么关系,从某种角度上来说,equals 和 hashcode 之间也没有必然联系。但是 Java 中存在一种数据结构,将 equals 和 hashcode 联系了起来,那就是 HashMap 及其子类。

HashMap 中键是不可以重复的,因此它的键就必须是不同的对象,那么这个时候就先用计算速度快的 hashcode 进行比较,若哈希值都不相等,那么这两个对象必然不相等,若是相等的,那么这个就有两种可能出现,一种情况是这两个对象是真的相等,另外一种情况就是出现了罕见的“哈希冲突”现象,那么这个时候就轮到 equals 来进行判断了!这样一来,就高效且快速地解决了键不可重复的问题。

从上面 HashMap 的比较中我们也可以看到,当我们自定义类型的时候,若要重写 equals 方法或者 hashcode 方法,请将它们两个同时进行重写,因为 Java 内置数据结构 HashMap 等判断键是否重复是需要同时调用它们两个。

综上,我们可以总结为下表:

比较方式== 运算符equals 方法hashcode 方法
比较速度快速默认情况下快速,一般情况下缓慢中等
比较值数值默认是内存地址,一般是对象属性哈希值

4.3 经典问题

为什么重写了 hashcode 方法还要重写 equals 方法?如果只重写 equals 方法而不重写 hashcode 方法会有问题吗?在 HashMap 中怎样体现出来的?

在 HashMap 中,键是不可以重复的,也就是说,它们的键都是不相同的,因此就要判断不同对象是否为同一对象。为了解决这个问题,HashMap 中同时调用了对象的 equals 方法和 hashcode 方法来进行判断。判断的部分源代码是这样的:

if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))return e;

hashcode 方法和 equals 方法都可以用来比较两个对象,但是二者有一些区别:

比较方式equals 方法hashcode 方法
比较速度

默认情况比较内存地址,速度快;

重写后一般比较内容,速度慢

计算哈希值,速度快
比较值内存地址或者内容(属性)哈希值

因此先用计算速度快的 hashcode 进行比较,这可以解决大部分问题,但由于可能出现“哈希冲突”,于是还需要 equals 方法解决。

正因为在判断键是否重复这一问题需要同时调用 equals 方法和 hashcode 方法,故我们自己定义的类中重写它们时必须两个一起重写。若只重写 equals 方法,而不重写 hashcode 方法,那么创建两个内容一样但内存地址不同的对象并存储在 HashMap 中时,会被当成两个键,而不是一个键,进而引发其他错误。

相关文章:

Java 中的 == 运算符、equals 方法和 hashcode 方法

一、 运算符 是 Java 中的一个运算符,用于比较两个对象,但在比较两个对象的时候需要根据比较类型分情况进行讨论。 1.1 基本数据类型与基本数据类型 基本数据类型之间通过 进行比较的时候,是直接比较它们的大小,而与它们的具体…...

第一个ArkTS项目实践-鸿蒙ArkTS

第一个ArkTS项目实践-ArkTS 第一个ArkTS项目实践-ArkTS自定义组件的组成配置属性与布局配置属性布局 改变组件状态循环渲染列表数据代码ToDoItem组件ToDoList页面 效果参考资料 第一个ArkTS项目实践-ArkTS 本篇文章是官网上视频对ArkTS开发实践的第一个视频,主要是引…...

【数据结构•堆】序列和的前n小元素(堆排序)

题目描述 问题:序列和的前 n n n小元素 给出两个长度为 n n n的有序表 A A A和 B B B, 在A和B中各任取一个, 可以得到 n 2 n^2 n2 个和. 求这些和最小的 n n n个。 输入输出格式 输入格式: 输入数据共三行。   第一行,一个整数值 n n …...

Keepalived+http高可用实战

环境准备: 两台安装了keepalived的服务器 ip:192.168.134.170;192.168.134.172 1、安装http服务 yum install httpd -y2、写一个测试页面 [rootlocalhost ~]# echo "hostname -I,web1 test page. " > /var/www/html/inde [rootlocalho…...

Linux文件系统管理

Linux文件系统管理 磁盘的组成与分区 计算机用于存取文件的硬件是磁盘,磁盘的组成主要有磁盘盘、机械手臂、磁盘读取头与主轴马达所组成, 而数据的写入其实是在磁盘盘上面。磁盘盘上面又可细分出扇区(Sector)与磁道(Track)两种单位, 其中扇区…...

MyBatis-Plugin源码全面分析

三、MyBatis-Plugin 1. 基本开发方式 需求:在MyBatis执行之前打印一行醒目的日志,携带参数 实现Interceptor接口: Intercepts(Signature(type Executor.class,method "query",args {MappedStatement.class,Object.class, RowB…...

Vscode 常用操作教程

一、语言换成中文 这是我们可以直接点击左边栏第四个图标搜索插件 chinese ,也可以直接ctrlshiftp快捷键也会出来如图所示图标,出来chinese 插件之后选择安装install,安装完成之后重新ctrlshiftp会出现如图所示页面 找到我的鼠标在的地方对应的中文,此时…...

Linux设备树详解

Linux 设备树详解 Linux 操作系统早期是针对个人电脑设备而开发的操作系统,而个人电脑处理器产商较为单一(例如只有 Intel,AMD)同时个人电脑产商均使用 Intel 或 AMD 制造的处理器,业界形成了统一的总线/硬件接口标准…...

.netcore grpc服务端流方法详解

一、服务端流式处理概述 客户端向服务端发送请求,服务端可以将多个消息流式传输回调用方和客户端流相反,客户端流发出请求,服务端可以传输一批消息给客户端,直至本次请求响应完全结束。针对文件分段传输下载,该方式非…...

python爬虫数据解析xpath、jsonpath,bs4

数据的解析 解析数据的方式大概有三种 xpathJsonPathBeautifulSoup xpath 安装xpath插件 打开谷歌浏览器扩展程序,打开开发者模式,拖入插件,重启浏览器,ctrlshiftx,打开插件页面 安装lxml库 安装在python环境中的Scri…...

go语言的database/sql结合squirrel工具sql生成器完成数据库操作

database/sql database/sql是go语言内置数据库引擎,使用sql查询数据库,配置datasource后使用其数据库操作方法对数据库操作,如下: package mainimport ("database/sql""fmt"_ "github.com/Masterminds…...

LVS集群和分布式

LVS 一.集群和分布式概念 1.1 集群 在计算机领域,集群早在 1960 年就出现,随着互联网和计算机相关技术的发展,现在 集群这一技术已经在各大互联网公司普及。 1.1.1 集群概念 计算机集群指一组通过计算机网络连接的计算机,它们…...

使用QT可视化设计对话框详细步骤与代码

一、创建对话框基本步骤 创建并初始化子窗口部件把子窗口部件放到布局中设置tab键顺序建立信号-槽之间的连接实现对话框中的自定义槽 首先前面三步在这里是通过ui文件里面直接进行的,剩下两步则是通过代码来实现 二、项目创建详细步骤 创建新项目 为项目命名 为…...

TFTP Server

简介 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。 TFTP和FTP的区别 安全性区别 FTP支持登录安全&…...

登录验证码实现

Hutool代码改造 Hutool 有参考文档&#xff1b;很多工具类&#xff1b;把一些功能都封装好&#xff1b;都不用你自己去写&#xff1b;直接调用它的工具类 它这里会详细告诉你引入方式Hutool <dependency><groupId>cn.hutool</groupId><artifactId>hu…...

2. 获取自己CSDN文章列表并按质量分由小到大排序(文章质量分、博客质量分、博文质量分)(阿里云API认证)

文章目录 写在前面步骤打开CSDN质量分页面粘贴查询文章url按F12打开调试工具&#xff0c;点击Network&#xff0c;点击清空按钮点击查询是调了这个接口https://bizapi.csdn.net/trends/api/v1/get-article-score用postman测试调用这个接口&#xff08;不行&#xff0c;认证不通…...

在Windows和MacOS环境下实现批量doc转docx,xls转xlsx

一、引言 Python中批量进行办公文档转化是常见的操作&#xff0c;在windows状态下我们可以利用changeOffice这个模块很快进行批量操作。 二、在Windows环境下的解决文案 Windows环境下&#xff0c;如何把doc转化为docx&#xff0c;xls转化为xlsx&#xff1f; 首先&#xff…...

【网络编程(二)】NIO快速入门

NIO Java NIO 三大核心组件 Buffer&#xff08;缓冲区&#xff09;&#xff1a;每个客户端连接都会对应一个Buffer&#xff0c;读写数据通过缓冲区读写。Channel&#xff08;通道&#xff09;&#xff1a;每个channel用于连接Buffer和Selector&#xff0c;通道可以进行双向读…...

【Vue-Router】嵌套路由

footer.vue <template><div><router-view></router-view><hr><h1>我是父路由</h1><div><router-link to"/user">Login</router-link><router-link to"/user/reg" style"margin-left…...

MySQL索引总结

MySQL索引总结 1.索引的概念、作用与使用场景 本质上就是减少读写磁盘的次数。 索引是一种特殊的文件&#xff0c;包含这对数据表中所有记录的引用指针&#xff0c;可以对表中的一列或多列创建索引&#xff0c;并指定索引的类型&#xff0c;每种类型都有对应数据结构实现。 …...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...