equals 和 hashCode 的区别

2023-05-16

1、equals 和 hashCode 的区别

equals() 和 hashcode() 这两个方法都是从 Object 类中继承过来的。hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。equals():反映的是对象的内存地址或者对象的内容是否相等。

Object 类实现 equals() 是对两个对象的地址值进行的比较(即比较引用是否相同,也就是内存地址是否相等)。

Object 类实现 hashCode() 方法,其实是调用 C++ 编写的本地方法,可以理解为一个产生随机数的本地方法。

如果你想了解 hashCode 值的底层原理的小伙伴可以点这个链接

Java 的 HashCode 底层生成分析

1.1 Java 中的两个规则

官方对 Object(父类) equals() 方法的解释

在这里插入图片描述

官方对 Object(父类) hashCode() 方法的解释
在这里插入图片描述

根据 JDK 8 官方文档对 Object(父类) 两个方法 equals() 和 hashCode() 的描述,我们可以得到两个规则

规则一:如果 equals 比较对象的内容相等,那么 HashCode 一定相等。(根据官方文档得出)

规则二:如果 equals 比较对象的内容不相等,那么 HashCode 可能相等,也可能不相等。(根据官方文档得出)

(验证规则二)

//代码
public class main {
    public static void main(String[] args) {
        Integer i = 97 ;
        String s = "a" ;
        System.out.println(i.hashCode());
        System.out.println(s.hashCode());
    }
}

//输出结果
i哈希值=97
a哈希值=97
    
//变量 i 和 变量 s 的 hashCode 值相等,但是变量 i 和 变量 s 的值并不相等

所以:HashCode 如果相等的情况下,那么对象的值不一定相等

变量 i 和 变量 s 的 hashCode 值相等是因为,Integer 和 String 类都对 hashCode() 方法进行了重写,所以他们会产生重复值,想知道具体为什么的小伙伴,点击这个链接

常用类 HashCode 生成规则

规则三:HashCode 如果相等的情况下,equals 比较对象不一定相等。(根据规则一二推断)

规则四:HashCode 如果不相等的情况下,equals 比较对象一定不相等。(根据规则一二推断)

1.2 总结

在重写 equals() 和 hashCode() 方法的时候,要遵循这规则一。

所以equals() 和 hashCode() 方法有一个重写了,那么最好这两个方法就一起重写,因为如果我们重写了 equals 方法的话,就有可能造成 equals 比较对象的内容相等, HashCode 不一定相等的情况。

5.3 代码示例

举例子说明
重写 equals 方法, equals 比较对象的内容相等, HashCode 不一定相等的情况。

//代码
public class main {
    public static void main(String[] args) {
        Dongkuku dkk = new Dongkuku("dkk", 12);
        Dongkuku dkk1 = new Dongkuku("dkk", 12);
        System.out.println("dkk hashCode="+dkk.hashCode());
        System.out.println("dkk1 hashCode="+dkk1.hashCode());
        System.out.println("dkk dkk1 equals判断="+dkk.equals(dkk1));
    }
}

public class Dongkuku {
    private String name ;
    private int age ;
    public Dongkuku(){}
    public Dongkuku(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

//运行结果
kk hashCode=1836019240
dkk1 hashCode=325040804
dkk dkk1 equals判断=false

重写 equals 之后

//代码
public class main {
    public static void main(String[] args) {
        Dongkuku dkk = new Dongkuku("dkk", 12);
        Dongkuku dkk1 = new Dongkuku("dkk", 12);
        System.out.println("dkk hashCode="+dkk.hashCode());
        System.out.println("dkk1 hashCode="+dkk1.hashCode());
        System.out.println("dkk dkk1 equals判断="+dkk.equals(dkk1));
    }
}

public class Dongkuku {
    private String name ;
    private int age ;
    public Dongkuku(){}
    public Dongkuku(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dongkuku)) return false;
        Dongkuku dongkuku = (Dongkuku) o;
        return age == dongkuku.age &&
                Objects.equals(name, dongkuku.name);
    }
    
}

//运行结果
dkk hashCode=1836019240
dkk1 hashCode=325040804
dkk dkk1 equals判断=true

重写 equals 方法之后, equals 比较对象的内容相等,但是 HashCode 并不相等,这就是问题所在(违背了上面的规则一),所以我们重写 equals 方法之后,最好也要把 hashCode 方法重写。

重写 equals 和 hashCode 之后

//代码
public class main {
    public static void main(String[] args) {
        Dongkuku dkk = new Dongkuku("dkk", 12);
        Dongkuku dkk1 = new Dongkuku("dkk", 12);
        System.out.println("dkk hashCode="+dkk.hashCode());
        System.out.println("dkk1 hashCode="+dkk1.hashCode());
        System.out.println("dkk dkk1 equals判断="+dkk.equals(dkk1));
    }
}

public class Dongkuku {
    private String name ;
    private int age ;
    public Dongkuku(){}
    public Dongkuku(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dongkuku)) return false;
        Dongkuku dongkuku = (Dongkuku) o;
        return age == dongkuku.age &&
                Objects.equals(name, dongkuku.name);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
    
}

dkk hashCode=3086217
dkk1 hashCode=3086217
dkk dkk1 equals判断=true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

equals 和 hashCode 的区别 的相关文章

  • 关于如何正确重写 object.GetHashCode() 的一般建议和指南

    根据MSDN http msdn microsoft com en us library system object gethashcode aspx 哈希函数必须具有以下属性 如果两个对象比较相等 则每个对象的 GetHashCode 方
  • 为什么 Scala 没有类型安全的 equals 方法?

    由于发明人强调Scala的类型安全我不明白对象上缺少 equals 方法 至少从案例类 允许仅检查具有相同类型的对象的相等性 我希望有一个方法 默认情况下实现此行为 当然 Java 的互操作性需要有一个可以与Any类型 但在很多情况下我只想
  • java.util.Set.contains(Object o) 的奇怪行为

    The doc http docs oracle com javase 6 docs api java util Set html contains java lang Object about java util Set contains
  • hashCode 等于 Integer.MIN_VALUE 的 Java 字符串

    是否存在 hashCode 完全等于 Integer MIN VALUE 的已知 Java 字符串 为哈希表编写测试有助于避免在执行余数运算之前在哈希码上运行 Math Abs 的常见错误 理想情况下 该字符串仅包含 ASCII 字符 但我
  • 深度比较 JavaScript 函数

    我正在阅读 Eloquent JavaScript 第三版 尽管我在 SO 上看到过一两个不同的答案 它们在执行逻辑上几乎与我的相同 但无论我如何调整它 我的工作似乎都不起作用 目标 创建一个深度比较函数 可以比较两个对象 并根据它们的属性
  • 整数值比较

    我是一名 Java 编码新手 我刚刚读到可以在 API 中用三种不同的方式描述整数类的变量 我有以下代码 if count compareTo 0 System out println out table count 这是在循环内部并且仅输
  • 在 Java 中对双精度值进行哈希处理

    我想知道如何在 Java 中对 double 进行哈希处理 我已经散列了其他原始数据和对象 我想我可以使用 hashcode 方法吗 从我所看到的来看 这看起来相当复杂 我遇到了一些关于创造种子的事情 我想知道关于如何解决这个问题的任何想法
  • Java - 为什么我不能使用 charAt() 来查看一个 char 是否等于另一个?

    我想查看字符串中的字符是否等于某个其他字符值 但我不知道字符串中的字符是什么 所以我使用了这个 if fieldNames charAt 4 f 但我收到错误 Operator cannot be applied to char jav l
  • Java .equals() 子类实例?为什么不调用超类 equals 而不是将其设为 Final 呢?

    它在 Object 中声明 equals Object javadoc 它是对称的 对于任何非空参考值 x 和 y 当且仅当 y equals x 返回时 x equals y 才应返回 true 真的 在示例代码中几乎所有地方我都看到被覆
  • 如何为排列编写一个好的 hashCode() ?

    在我的程序中 我处理很多大小的列表n所有这些都是 1 n 我的问题是我把这些排列放在HashMaps and HashSets 我需要一个好的hashCode 这样可以避免太多的碰撞 我想到的所有解决方案都会导致大量冲突或溢出 如何为排列编
  • 在 Java 中使用 String 和 Object 的 equals() 方法

    Object o1 new Object Object o2 new Object o1 o2 System out println o1 equals o2 它返回false 它可以返回true 如果评论被删除 为什么同样的事情不适用于S
  • 如何使用 System.HashCode.Combine 来处理超过 8 个值?

    NET 标准 2 1 NET 核心 3介绍 https github com dotnet corefx issues 14354 System HashCode https learn microsoft com en us dotnet
  • Java 中 null 对象的 hashcode 必须是什么?

    根据此评论post https stackoverflow com questions 11184041 how is hashcode calculated for null object hascode of null objects
  • 如何为特定类编写hashCode方法?

    我正在尝试为我的简单类生成 hashCode 方法 但我没有得到任何结果 我将不胜感激任何帮助 我已经实现了 equals 方法 如下所示 并且还想知道是否需要实现compareTo 方法 我已经导入 java lang Character
  • 两个实例具有相同的哈希码但不相等

    我正在阅读下面引用的一篇文章中的段落 题为 Java 理论与实践 哈希它 有效且正确地定义 hashCode 和 equals http www ibm com developerworks java library j jtp05273
  • 字符串等于和 == 与字符串连接[重复]

    这个问题在这里已经有答案了 我试图理解字符串连接与字符串比较的输出 需要明确的是 我有一个类使用 和 equals 来比较两个字符串 我试图将 和 equals 的输出连接到一个字符串 equals 的输出是 concats 但是 的输出是
  • equals 和 hashcode 的不同字段

    我同意这篇文章的声明在Java中重写equals和hashCode时应该考虑哪些问题 https stackoverflow com questions 27581 overriding equals and hashcode in jav
  • Java的hashCode可以为不同的字符串产生相同的值吗?

    使用java的哈希码函数是否可以为不同的字符串提供相同的哈希码 或者如果可能的话 其可能性的 是多少 Java 哈希码是 32 位 它散列的可能字符串的数量是无限的 所以是的 会发生冲突 百分比是没有意义的 项目 字符串 的数量是无限的 而
  • 在优先级相等的情况下保持优先级队列插入顺序

    我正在使用priorityQueue 来实现BFS 我想在插入时和弹出后在优先级相同的情况下保持插入顺序 我重写了 equals 方法 如下所示 并且插入顺序在插入时按预期保持 但 一旦我进行删除或民意调查 元素的顺序发生变化 即使在轮询中
  • “Equals”和“SequenceEqual”之间的区别?

    是否存在以下情况 Equals MyList1 MyList2 MyList1 SequenceEqual MyList2 两者之间有什么区别 Equals obj1 obj2 and obj1 Equals obj2 Thanks Equ

随机推荐

  • Andrews定理的证明(对称单峰多项式乘积保持对称单峰性)

    tags Maths 预备定义 原始文献A Theorem on Reciprocal Polynomials with Applications to Permutations and Compositions 对称多项式 对称 reci
  • 双向链表的增删改查C++完整实现

    tags C 43 43 DSA LinkedList 写在前面 写一下双向链表的增删改查 用C 43 43 实现 完整代码可以看我的GitHub 节点类 链表类 节点 span class token keyword class span
  • 单向环形链表的增删改查C++完整实现

    tags C 43 43 DSA 写在前面 刚写了双向链表的 趁热打铁再来一个环形链表的 这次就有点复杂了 但是还是可以接受的 实现环形链表的关键就是不能通过判断是否遍历到空节点来结束循环 这会导致死循环 只能用指针是否遍历回到头结点来判断
  • FL水果编曲20.8中文版下载 flstudio语言修改中文教程

    FL Studio中文版一般又称水果音乐制作 水果音乐软件手机版可以记录 xff0c 序列编辑 混合和渲染完成的歌曲等 FL Studio xff08 水果音乐制作 xff09 软件含43种虚拟音源 可同时录制64轨音频轨 增强音频编辑与后
  • 双向环形链表的C++增删改查完整实现

    tags C 43 43 DSA 写在前面 最后写一下双向循环链表吧 跟前面的没啥太大区别 注意取余操作以及循环跳出的条件 代码 GitHub 节点类 链表类 节点类 和双向链表一模一样 span class token keyword c
  • 牛客网ACM模式输入输出11道题目的C++解答(C标准IO版)

    tags C 43 43 Interview 写在前面 之前写过关于牛客网的输入输出的题目 但是是用C 43 43 的标准IO写的 虽然方便 但是据说速度会很慢 这里还是再用C重写一遍 主要用到了scanf和printf 地址 牛客竞赛 A
  • 面试题: C++类内静态成员必须在类外初始化吗? --分析与示例

    tags C 43 43 OOP 写在前面 最近看到了这样一个题 静态数据成员定义之后 xff0c 必须在类外进行初始化 看完了Effective系列之后 我会给出答案 错误 为什么呢 下面来深入分析一下 非常量静态数据成员 看下面这个例子
  • C++字符串+和push_back创建字符串的性能比较

    tags C 43 43 String 写在前面 刷力扣 415 字符串相加 时候发现这样一个现象 使用 s1 span class token operator 61 span span class token generic funct
  • C++并发编程实战笔记(一)线程概念与基本控制

    tags C 43 43 Concurrency 写在前面 在C 43 43 中实现多线程还是很容易的 不像C的pthreads接口 下面来总结一下C 43 43 多线程的一些基本操作 包括线程的创建 合并 分离 获取ID等操作 主要参考了
  • 差分数组C++实现与力扣题目总结

    tags DSA C 43 43 LeetCode 写在前面 总结一下经典的差分数组方法 华为机试刚考了 思路很简单 但是没遇到的话想写出来还是有点难度的 参考了 labuladong 的博客 里面的代码是 Java 实现的 这里用 C 4
  • 拓扑排序的C++实现

    tags C 43 43 DSA Sort GT 写在前面 写一下有向无环图 DAG Directed Acyclic Graph 上的拓扑排序 废话不多说了 介绍部分大家可以参考算法导论或者 oi wiki https oi wiki o
  • Windows上使用winedt提示系统找不到文件的情况分析+texlive安装与配置

    tags LaTeX Debug 问题 最近有同学问我在 Windows 上使用 WinEdt 这款编辑器为什么会提示系统找不到文件 我搜索一下发现大概率是 TeX L i v e
  • LaTeX常见错误与常用Debug方法总结

    tags LaTeX Debug 前言 在LaTeX中 常常会出现很多意想不到的错误 我一开始学习的时候 就常常被这种看似玄学的错误整的焦头烂额 常常是打开一堆CSDN界面各处翻找而没有一个合适的解决方案 之后在不断的使用和摸索中 我对于
  • SQL中的七种关联代数与额外关联代数总结

    tags SQL 写在前面 总结一下 cmu15445 第一节课的内容 前面的可以不听 主要是 40 分钟往后的内容 视频 01 Relational Model amp Relational Algebra CMU Intro to Da
  • 如何恢复MAC苹果电脑系统数据文件恢复详细教程

    Mac电脑也可以使用shift加delete进行文件的永久删除 xff0c 因为这样不仅方便快速 xff0c 还能够不占回收站的内存 但是如果你不小心永久删除了重要的数据 xff0c 也就意味着不能从回收站还原了 xff0c 该怎么办呢 x
  • 快速解决 MacOS 启动台程序删除之后图标仍存在显示问号的问题

    解决 第一个方案是更新 sqlite 数据库 但是这个方案会改动启动台图标的顺序 还是不推荐的 第二个方案最近摸索出来的 直接把图标拖拽到废纸篓即可 怒赞
  • Jekyll博客中添加分类与多目录存放博客的方法

    categories Frontend tags Frontend HTML 写在前面 最近发现一个问题 博客数量越来越多了 都放在 posts下实在是有点不方便 于是想着分个类 Google 了一圈 找到了一篇不错的博客 如下 Jekyl
  • 推荐三本wpf的书

    1 葵花宝典WPF 2 WPF深入浅出 3 WPF编程宝典 个人粗略浏览了一遍 xff0c 第二本收获比较多 xff0c 第三本比较全面 xff0c 第一本相对来说没那么枯燥 xff0c 前两本我有pfd的资源文件 xff0c 需要的留言我
  • C++实现A钱买A鸡问题

    总时间限制 10000ms 单个测试点时间限制 1000ms 内存限制 131072kB 描述 A钱买A鸡 的问题 xff1a 3文钱可以买1只公鸡 xff0c 2文钱可以买1只母鸡 xff0c 1文钱可以买3只小鸡 xff0c 要用A文钱
  • equals 和 hashCode 的区别

    1 equals 和 hashCode 的区别 equals 和 hashcode 这两个方法都是从 Object 类中继承过来的 hashCode xff1a 计算出对象实例的哈希码 xff0c 并返回哈希码 xff0c 又称为散列函数