1、==、equals、hashCode底层原理?重写场景?

目录

一、核心定义&存在意义&基础作用

[1. ==](#1. ==)

是什么

为什么存在

作用

[2. equals()](#2. equals())

是什么

为什么存在

作用

[3. hashCode()](#3. hashCode())

是什么

为什么存在

作用

二、底层原理(原生源码+JVM层级)

[1. == 底层原理](#1. == 底层原理)

[2. equals() 底层原理(原生Object源码)](#2. equals() 底层原理(原生Object源码))

[3. hashCode() 底层原理](#3. hashCode() 底层原理)

三、三者联动规范(强制底层契约)

四、重写场景(精准业务落地)

[1. 什么时候必须重写 equals()](#1. 什么时候必须重写 equals())

[2. 什么时候必须重写 hashCode()](#2. 什么时候必须重写 hashCode())

[3. 什么时候不用重写](#3. 什么时候不用重写)

[4. 补充:String/JDK常用类现状](#4. 补充:String/JDK常用类现状)


一、核心定义&存在意义&基础作用

1. ==

是什么

Java原生运算符,语法级比较符号,不依赖任何方法实现。

为什么存在

JVM需要一套底层原生机制,直接判定两个变量 内存指向/基础值是否完全一致。

作用

  • 比较基本数据类型 :判断栈中存储的字面数值是否相等;
  • 比较引用数据类型:判断两个引用变量**堆内存地址(对象指针)**是否指向同一个对象。

2. equals()

是什么

Object类中定义的 public boolean equals(Object obj) 实例方法,所有类默认继承。

为什么存在

==仅能比内存地址,业务中需要 比对对象内容/属性逻辑相等,而非同一个内存对象,因此提供可自定义的逻辑比较入口。

作用

实现 业务层面的对象内容相等判定,开发者可重写该方法,自定义相等规则。

3. hashCode()

是什么

Object类中定义的 public native int hashCode() 本地方法,返回对象int类型哈希码。

为什么存在

配合哈希表集合(HashMap/HashSet/HashTable)实现 高效存取、快速判重;哈希表先靠哈希码定位桶,再用equals精准比对,降低比对开销。

作用

  • 为对象生成固定哈希编码,确定哈希表存储桶位置;
  • 约束规范:两个equals=true的对象,必须哈希码相同;减少equals全量比对次数。

二、底层原理(原生源码+JVM层级)

1. == 底层原理

  1. 基本类型(byte/short/int/long/float/double/char/boolean):
    变量直接在虚拟机栈存 真实数值
    ==直接比对栈内两个数值的二进制数据,完全一致则返回true。
  2. 引用类型:
    变量在栈中存 对象堆内存的地址指针,==直接比对两个指针的内存地址值;
    只有指向堆中同一个对象,才返回true。
    无任何方法调用,纯JVM指令级地址/数值比对。

2. equals() 底层原理(原生Object源码)

Object类原生源码:
public boolean equals(Object obj) { return (this == obj); }
底层原生实现: 直接复用 == 地址比对

  • 未重写时:equals和==比对逻辑完全一致,只比内存地址;
  • 重写后:开发者自定义属性比对逻辑,不再依赖地址比对。

3. hashCode() 底层原理

  1. 原生是native本地方法,由JVM底层实现,非Java代码编写;
  2. JVM默认生成规则:基于对象堆内存地址、对象头哈希字段、随机数、对象生命周期生成int整数;
  3. 原生规则:
  • 同一个对象,多次调用hashCode,返回值始终一致;
  • 不同对象,大概率哈希码不同(存在哈希碰撞);
    4.哈希表工作底层:
    存元素:计算hashCode→取模定位哈希桶→桶内用equals逐个比对;
    判重:先比hashCode,不同直接判不相等;相同再执行equals精准校验。

三、三者联动规范(强制底层契约)

  1. 若a.equals(b) = true → 必须保证 a.hashCode() == b.hashCode();
  2. 若a.hashCode() != b.hashCode() → 必须保证 a.equals(b) = false;
  3. 若a.hashCode() == b.hashCode() → a.equals(b)可true可false(哈希碰撞);
  4. 只重写equals不重写hashCode:违反契约,HashMap/HashSet会出现逻辑异常(相同内容对象存重复、取不出)。

四、重写场景(精准业务落地)

1. 什么时候必须重写 equals()

  1. 自定义实体类(User/Order/Student等),需要按属性判定对象逻辑相等,而非地址相等;
  2. 对象需要存入HashSet、作为HashMap的key,必须重写equals做内容精准判重;
  3. 业务需求:两个对象所有核心字段一致即判定为同一个业务数据。

2. 什么时候必须重写 hashCode()

只要重写了equals(),就必须同步重写hashCode()
专属场景:对象要放入所有哈希结构集合(HashMap、HashSet、LinkedHashMap等),不重写会导致:

  • 内容相等的两个对象,hashCode不同,存到不同哈希桶;
  • 集合判重失效、get(key)获取不到数据、去重失败。

3. 什么时候不用重写

  1. 实体类仅做数据传输,无需比对相等、不存入哈希集合;
  2. 枚举类、基础包装类(Integer/String已JDK底层重写完毕,直接用);
  3. 只靠==地址比对就能满足所有业务逻辑。

4. 补充:String/JDK常用类现状

String、Integer、Long、BigDecimal等JDK类:
已原生重写equals(比字符/数值内容)+ 重写hashCode(按内容生成哈希码),直接使用即可满足内容相等比对。

相关推荐
WolfGang0073212 小时前
代码随想录算法训练营 Day38 | 动态规划 part11
算法·动态规划
松☆3 小时前
C++ 算法竞赛题解:P13569 [CCPC 2024 重庆站] osu!mania —— 浮点数精度陷阱与 `eps` 的深度解析
开发语言·c++·算法
jr-create(•̀⌄•́)3 小时前
正则化和优化算法区别
pytorch·深度学习·神经网络·算法
li星野4 小时前
刷题:数组
数据结构·算法
tankeven5 小时前
HJ182 画展布置
c++·算法
CS_Zero7 小时前
无人机路径规划算法——EGO-planner建模总结—— EGO-planner 论文笔记(一)
论文阅读·算法·无人机
杰梵7 小时前
聚酯切片DSC热分析应用报告
人工智能·算法
@BangBang7 小时前
leetcode (4): 连通域/岛屿问题
算法·leetcode·深度优先
Ulyanov7 小时前
像素迷宫:路径规划算法的可视化与实战
大数据·开发语言·python·算法