推荐阅读:

一线架构师总结SpringBoot,Cloud,Nginx与Docker,不信你搞不懂

47天洒热血复习,我终于“挤进”了字节跳动(附面经+学习笔记)

五年时间,从蘑菇街到阿里架构师,多亏我读了这些“技术栈”

在每个类中,在重写 equals 方法的时侯,一定要重写 hashcode 方法。如果不这样做,你的类违反了 hashCode的通用约定, 这会阻止它在 HashMap 和 HashSet 这样的集合中正常工作。 根据 Object 规范,以下时具体约定。

  1. 当在一个应用程序执行过程中, 如果在 equals 方法比较中没有修改任何信息, 在一个对象上重复调用 hashCode 方法时,它必须始终返回相同的值。从一个应用程序到另一个应用程序的每一次执行返回的值 可以是不一致的。
  2. 如果两个对象根据 equals(Object) 方法比较是相等的,那么在两个对象上调用 hashCode 就必须产生的 结果是相同的整数。
  3. 如果两个对象根据 equals(Object) 方法比较并不相等,则不要求在每个对象上调用 hashCode 都必须产生不同的结果。但是,程序员应该意识到,为不相等的对象生成不同的结果可能会提高散列表(hash tables) 的性能。

当无法重写 hashCode 时,所违反第二个关键条款是:相等的对象必须具有相等的哈希码(hash code)

创建一个Point类,有两个成员变量x和y,并重写了equals方法

    public class Point {        private final int x, y;            public Point(int x, int y) {            this.x = x;            this.y = y;        }                @Override        public boolean equals(Object obj) {            if (this == obj) return true;            if (!(obj instanceof Point)) return false;            Point point = (Point) obj;            return x == point.x && y == point.y;        }    }

在main方法中测试一下

    public static void main(String[] args) {          Point p1 = new Point(1, 2);          Point p2 = new Point(1, 2);          System.out.println(p1.equals(p2));// true              Map map = new HashMap<>();          map.put(p1, "p1");          System.out.println(map.get(p2)); // null          }

你可能觉得 map.get(p2) 应该返回字符串 p1, 但是却返回null, 这是因为Point类并没有重写hashCode方法,导致两个相等的实例p1和p2返回了不同的哈希码,违反了hashCode的约定,put方法把实例p1放到了一个哈希桶(hash bucket)中,但因为p2的哈希码不等于p1的哈希码,所以get方法会从其它哈希桶中去查找。

解决这个方法很简单,只需要重写Point类的hashCode方法。

    @Override    public int hashCode() {        int result = Integer.hashCode(x);        result = 31 * result + Integer.hashCode(y);        return result;    }

再次测试

    public static void main(String[] args) {          Point p1 = new Point(1, 2);          Point p2 = new Point(1, 2);          System.out.println(p1.equals(p2));// true              Map map = new HashMap<>();          map.put(p1, "p1");          System.out.println(map.get(p2)); // p1      }

这次你会发现map.get(p2) 返回的就是字符串p1了, 因为hashCode这个方法会返回一个简单的确定性计算的结果,它的唯一的输入是 Point实例中的两个重要的属性x和y,所以显然相等的 Point实例具有相同的哈希码。

此外Objects 类有一个静态方法,它接受任意数量的对象并为它们返回一个哈希码。这个名为 hash 的方法可以 让你编写一行 hashCode 方法,其质量与根据这个项目中的上面编写的方法相当。

    @Override    public int hashCode() {    return Objects.hash(x, y);    }

注意事项

  • 当你写完 hashCode 方法后,请一定问一下自己是否满足相等的实例有相同的哈希码这一条件。
  • hashCode中涉及到的属性应与equals中保持一致,不要试图从哈希码计算中排除重要的属性来提高性能。

总之,每次重写 equals 方法时都必须重写 hashCode 方法,否则程序将无法正常运行。你的 hashCode 方 法必须遵从 Object 类指定的常规约定,并且必须执行合理的工作,将不相等的哈希码分配给不相等的实例。

作者:多多爱吃鱼

链接:https://juejin.im/post/5e0226bb6fb9a0165936f44b

hashcode相等的两个对象一定相等吗_为什么重写 equals方法时一定要重写hashCode方法?...相关推荐

  1. Java重写equals方法时为什么要重写hashCode方法

    在我们平时编写Java代码时,重写equals方法时一定要重写hashCode方法,这是为什么呢? 在讨论这个问题前,我们先看下Object类中hashCode方法和equals方法. hashCod ...

  2. 为什么重写equals方法时一定要重写hashCode方法

    在每个类中,在重写equals方法的时侯,一定要重写hashcode方法. 根据Object规范,规范约定: 如果两个对象通过equals方法比较是相等的,那么它们的hashCode方法结果值也是相等 ...

  3. JavaSE——为什么重写equals的同时一定要重写hashCode?

    文章目录: 1.引出话题 2.关于equals方法 3.关于hashCode方法 4.为什么要一起重写这两个方法? 5.总结 1.引出话题 equals 方法和 hashCode 方法是 Object ...

  4. 为什么重新new两个线程线程号相同_面试官每次问我关于线程间通信方法,我都回答的很糟糕...

    线程的生命周期 废话不多写.首先我们先回顾回顾,理解下线程的生命周期,以及不同的阶段的区别: 新建状态(NEW) 当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配 ...

  5. python提供两个对象身份比较操作符_标准类型对象比较操作符

    标准类型对象比较操作符 (2008-08-31 12:22:17) 标签: it 标准类型对象身份比较操作符 Python 提供了is和is not操作符来测试两个变量是否指向同一个对象. 像下面这样 ...

  6. 重写equals方法一定要重写hashcode方法吗

    今天这句话疑惑了我一会,我就很疑惑啊,我单纯的比个对象我干嘛非得重写hashCode方法,为什么网上都在说一定要一定要,难道这不是分情况吗????? 不需要重写的情况 我们先来看Object的equa ...

  7. 为什么重写equals()就要重写hashCode()

    文章目录 一.前言 二.hashCode()方法 三.equals()方法 四.hashCode() 与 equals() 4.1 不会创建"类对应的散列表"的情况 4.2 会创建 ...

  8. 重写 equals 方法就一定要重写 hashCode 方法?其实有个前提

    作者 l 会点代码的大叔(CodeDaShu) 如果问到 == 和 equals 的区别,相信很多程序员同学都能脱口而出:一个是判断地址,一个是判断内容. 但是如果继续追问:"你重写过 eq ...

  9. java 为什么重写equals一定要重写hashcode?

    前言 最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题. 初步探索 首先我们要了解equals方法是什么,hashcode方法是什么. equals ...

最新文章

  1. 钉钉头像大小设置 阿里cdn尺寸截取参数设置
  2. shell单例-处理方案
  3. AI开发者大会之计算机视觉技术实践与应用:2020年7月3日《RPA+AI助力政企实现智能时代的人机协同》、《5G风口到来,边缘计算引领数据中心变革》、《数字化时代金融市场与AI算法如何结合?》
  4. 使用poi写入doc文档中文档打不开_基于NodeJS和浏览器的PDF文档引擎——PDFKit
  5. MyBatis3 用log4j在控制台输出 SQL----亲测,真实可用
  6. leetcode27:移除元素(暴力+双指针)
  7. 树链剖分入门+HYSBZ - 1036树的统计Count
  8. bsp模型适用于图计算_【论文解读】目标检测之RFBnet模型
  9. 【C语言】《程序设计基础(C语言)》自编题解索引
  10. jq监听页面的滚动事件,
  11. 常用shell命令归纳总结
  12. java海康摄像头添加人脸_java及opencv实现调用本地摄像头、网络摄像头完成人脸检测、人脸收集、人脸识别、性别识别...
  13. 基于python的语料库数据处理_基于Python的语料库数据处理(三)
  14. 自定义View进阶-手绘地图(二)
  15. 计算机无法超过人类智慧,计算机的智力会超过人类吗?
  16. C++: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  17. Redis-5.0.5集群配置
  18. 如何秒下单?python的淘宝秒杀抢购下单源码参考
  19. ubuntu 百度云盘
  20. Spring Cloud 微服务开放平台接口

热门文章

  1. SQLite.NET提供程序的选择
  2. unity3d小小白之导入素材、添加天空盒
  3. Android应用实例收藏管理
  4. Webpy 0.3新手指南
  5. linux 查看剩余内存
  6. AtomicInteger源码注释
  7. js运动 运动效果留言本
  8. iframe高度动态自适应
  9. python 3.10 新增 switch-case 简介
  10. linux rsync 本地 远程 增量 备份 同步工具 问题集合