hashcode相等的两个对象一定相等吗_为什么重写 equals方法时一定要重写hashCode方法?...
推荐阅读:
一线架构师总结SpringBoot,Cloud,Nginx与Docker,不信你搞不懂
47天洒热血复习,我终于“挤进”了字节跳动(附面经+学习笔记)
五年时间,从蘑菇街到阿里架构师,多亏我读了这些“技术栈”
在每个类中,在重写 equals 方法的时侯,一定要重写 hashcode 方法。如果不这样做,你的类违反了 hashCode的通用约定, 这会阻止它在 HashMap 和 HashSet 这样的集合中正常工作。 根据 Object 规范,以下时具体约定。
- 当在一个应用程序执行过程中, 如果在 equals 方法比较中没有修改任何信息, 在一个对象上重复调用 hashCode 方法时,它必须始终返回相同的值。从一个应用程序到另一个应用程序的每一次执行返回的值 可以是不一致的。
- 如果两个对象根据 equals(Object) 方法比较是相等的,那么在两个对象上调用 hashCode 就必须产生的 结果是相同的整数。
- 如果两个对象根据 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方法?...相关推荐
- Java重写equals方法时为什么要重写hashCode方法
在我们平时编写Java代码时,重写equals方法时一定要重写hashCode方法,这是为什么呢? 在讨论这个问题前,我们先看下Object类中hashCode方法和equals方法. hashCod ...
- 为什么重写equals方法时一定要重写hashCode方法
在每个类中,在重写equals方法的时侯,一定要重写hashcode方法. 根据Object规范,规范约定: 如果两个对象通过equals方法比较是相等的,那么它们的hashCode方法结果值也是相等 ...
- JavaSE——为什么重写equals的同时一定要重写hashCode?
文章目录: 1.引出话题 2.关于equals方法 3.关于hashCode方法 4.为什么要一起重写这两个方法? 5.总结 1.引出话题 equals 方法和 hashCode 方法是 Object ...
- 为什么重新new两个线程线程号相同_面试官每次问我关于线程间通信方法,我都回答的很糟糕...
线程的生命周期 废话不多写.首先我们先回顾回顾,理解下线程的生命周期,以及不同的阶段的区别: 新建状态(NEW) 当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配 ...
- python提供两个对象身份比较操作符_标准类型对象比较操作符
标准类型对象比较操作符 (2008-08-31 12:22:17) 标签: it 标准类型对象身份比较操作符 Python 提供了is和is not操作符来测试两个变量是否指向同一个对象. 像下面这样 ...
- 重写equals方法一定要重写hashcode方法吗
今天这句话疑惑了我一会,我就很疑惑啊,我单纯的比个对象我干嘛非得重写hashCode方法,为什么网上都在说一定要一定要,难道这不是分情况吗????? 不需要重写的情况 我们先来看Object的equa ...
- 为什么重写equals()就要重写hashCode()
文章目录 一.前言 二.hashCode()方法 三.equals()方法 四.hashCode() 与 equals() 4.1 不会创建"类对应的散列表"的情况 4.2 会创建 ...
- 重写 equals 方法就一定要重写 hashCode 方法?其实有个前提
作者 l 会点代码的大叔(CodeDaShu) 如果问到 == 和 equals 的区别,相信很多程序员同学都能脱口而出:一个是判断地址,一个是判断内容. 但是如果继续追问:"你重写过 eq ...
- java 为什么重写equals一定要重写hashcode?
前言 最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题. 初步探索 首先我们要了解equals方法是什么,hashcode方法是什么. equals ...
最新文章
- 钉钉头像大小设置 阿里cdn尺寸截取参数设置
- shell单例-处理方案
- AI开发者大会之计算机视觉技术实践与应用:2020年7月3日《RPA+AI助力政企实现智能时代的人机协同》、《5G风口到来,边缘计算引领数据中心变革》、《数字化时代金融市场与AI算法如何结合?》
- 使用poi写入doc文档中文档打不开_基于NodeJS和浏览器的PDF文档引擎——PDFKit
- MyBatis3 用log4j在控制台输出 SQL----亲测,真实可用
- leetcode27:移除元素(暴力+双指针)
- 树链剖分入门+HYSBZ - 1036树的统计Count
- bsp模型适用于图计算_【论文解读】目标检测之RFBnet模型
- 【C语言】《程序设计基础(C语言)》自编题解索引
- jq监听页面的滚动事件,
- 常用shell命令归纳总结
- java海康摄像头添加人脸_java及opencv实现调用本地摄像头、网络摄像头完成人脸检测、人脸收集、人脸识别、性别识别...
- 基于python的语料库数据处理_基于Python的语料库数据处理(三)
- 自定义View进阶-手绘地图(二)
- 计算机无法超过人类智慧,计算机的智力会超过人类吗?
- C++: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
- Redis-5.0.5集群配置
- 如何秒下单?python的淘宝秒杀抢购下单源码参考
- ubuntu 百度云盘
- Spring Cloud 微服务开放平台接口