为什么重写equals()就要重写hashcode()
阿里巴巴开发规范
只要重写 equals,就必须重写 hashCode
因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方法
如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals
Object作者建议
相同的对象必然是相同的哈希值,不同的哈希值是不同的对象
在开发规范和Object作者建议 中都是只要重写 equals, 就必须重写 hashCode 为什么?
要明白重写equals的原因要先明白equals是什么,与之关联的 ==,hashCode又是什么?
== :是对于基本数据类型的值比较
equals :定义在JDK的Object.java中 这就意味着Java中的任何类都包含有equals()函数
equals默认下情况比较两个对象的地址是否相同 如果对象重写了equals()方法,比较两个对象的内容是否相等
但很多类都重写了equals方法,像String,基本数据的包装类等把他变成了值比较 所以一般情况下equals比较的是值是否相等
hashCode :hashCode() 定义也在JDK的Object.java中
hashCode() 的作用是获取哈希码,它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
hashCode() 和 equals() 有什么关系?
有关系,但不能说完全有关系 以“类的用途”分2种情况来说明
类对应的散列表(散列表就是同时运用了数组和链表 如 HashMap,HashSet,HashTable等这些本质是散列表的数据结构中)
1 不会创建“类对应的散列表”
在这种情况下,该类的“hashCode() 和 equals() ”是没有任何关系的 equals() 用来比较该类的两个对象是否相等,而hashCode() 则根本没有任何作用
可以看到equals是相等的,但hashCode值是不同的,在这种情况下hashCode值是没有任何作用的
2 会创建“类对应的散列表”
在这种情况下,该类的“hashCode() 和 equals() ”是有关系的: 如果两个对象相等,那么它们的hashCode()值一定相同。
这里的相等是指,通过equals()比较两个对象时返回true。
如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode()相等,即两个键值对的哈希值相等。
然而哈希值相等,并不一定能得出键值对相等,此时就出现所谓的哈希冲突场景。也就是Set 存储的是不重复的对象
(hashSet底层是hashMap)
所以说在散列表中 如果重写了 equals() 而未重写 hashcode() 方法,可能就会出现两个没有关系的对象 equals 相同
(因为equal都是根据对象的特征进行重写的),但 hashcode 不相同的情况, 因为在散列表数据结构中要保持key值的唯一,
不然会进行覆盖,通过equals来比较两个key是否相同,也能达到要求,只不过就要和map中的key一个一个的用equals比较,
如果map中有很多元素了,那么效率可能会很低,hashCode方法是根据对象的内存地址经过哈希算法(数据压缩技术,尽量分散
减少哈希冲突)得来的 使用hashCode的一个目的是“分组”,同一个链表上的key的 hashcode是一样的,如果不重写hashcode,
那么两个相同内容的对象,就会放在不同的链表上,那么就会存在两个相同的key。所以就要重写hashcode,
保证有相同内容的对象有相同的hashcode。而且hashcode的结果跟对象的属性有关。如果属性不参与hashcode的计算,
那么这个hash算法就无意义。
如果自定义对象做为 Map 的键,那么必须重写 hashCode 和 equals
这个就是开发规范和Object作者建议的原因
为什么重写equals()就要重写hashcode()的更多相关文章
- 为什么重写了equals() 就要重写hashcode()
规定:1.两个对象相等,则hashcode也一定是相等的:2.两个对象相等,对两个对象分别调用equals()都返回 true:3.两个对象有相同的hashcode,但不一定相等 为什么重写了equa ...
- 为什么重写equals还要重写hashcode??
equals和hashcode是object类下一个重要的方法,而object类是所有类的父类,所以所有的类都有这两个方法 equals和hashcode间的关系: 1.如果两个对象相同(即equal ...
- 【原创】关于java对象需要重写equals方法,hashcode方法,toString方法 ,compareto()方法的说明
在项目开发中,我们都有这样的经历,就是在新增表时,会相应的增加java类,在java类中都存在常见的几个方法,包括:equals(),hashcode(),toString() ,compareto( ...
- 为什么重写equals必须重写hashCode
目录 equals常见面试题 为什么要重写equals 重写equals不重写hashCode会存在什么问题 总结 equals常见面试题 在开始聊之前,我们先看几个常见的面试题,看看你能不能都回答上 ...
- 为什么重写equals必须重写hoshCode的基础分析
为什么重写equals必须重写hoshCode的基础分析 1.我们先来了解下原生的equals和hashCode代码 原生equals:它判断的是两个对象是否相等 原生hashCode值:它是根据内存 ...
- 为什么要重写equals()方法与hashCode()方法
在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写equals方法我们是继承了object ...
- Hibernate中为什么要重写equals方法和hashcode方法
1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...
- 为什么重写equals()必须重写hashCode()
主要原因是因为hashCode是用对象的内部地址转换成一个整数的,而equals比较得是两个对象,或者是两个对象的内容 如果你重写了equals,而保留hashCode的实现不变,那么很可能两个对象明 ...
- JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法
在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...
随机推荐
- HouseRobber II
// // Created by Administrator on 2021/7/27. // #ifndef C__TEST01_HOUSEROBBER2_HPP #define C__TEST01 ...
- 如何用LOTO示波器TDR方法测试电线长度?
TDR也就是时域反射(Time-domain reflectometer),它可以通过观察导线中反射回来的电信号波形对导线长度进行测量,或者对传输导线的阻抗特性进行分析评估. 我们经常会碰到的TDR的 ...
- char数据可以放入int[]中会自动转换
int[] ary ={'b','c','a','d','e','f'};System.out.println(ary[0]);//98String str = new String(ary, 2, ...
- tomcat的log日志乱码解决方案
Intellij idea Tomcat输出log中文乱码 配置tomcat在VM options添加-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 重启后控 ...
- html+css第二篇
<img src="图片地址" alt="图片名"/> 图片(单标签)alt属性 是图片名字,是给百度搜索引擎抓取使用: a标签: 链接/下载/锚点 ...
- Vulnhub-Empire: LupinOne题解
Vulnhub-Empire: LupinOne题解 本靶机为Vulnhub上Empire系列之LupinOne,地址:EMPIRE: LUPINONE 扫描与发现 利用arp-scan命令扫描靶机I ...
- 洛谷 P6295 - 有标号 DAG 计数(生成函数+容斥+NTT)
洛谷题面传送门 看到图计数的题就条件反射地认为是不可做题并点开了题解--实际上这题以我现在的水平还是有可能能独立解决的( 首先连通这个条件有点棘手,我们尝试把它去掉.考虑这题的套路,我们设 \(f_n ...
- Codeforces 1322D - Reality Show(DP)
Codeforces 题面传送门 & 洛谷题面传送门 首先这个消消乐的顺着消的过程看起来有点难受,DP 起来有点困难.考虑对其进行一个转化:将所有出场的人按照攻击力从小到大合并,然后每次将两个 ...
- 洛谷 P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I(分块+卡常)
洛谷题面传送门 zszz,lxl 出的 DS 都是卡常题( 首先由于此题强制在线,因此考虑分块,我们那么待查询区间 \([l,r]\) 可以很自然地被分为三个部分: 左散块 中间的整块 右散块 那么这 ...
- Python list的深拷贝和浅拷贝
深拷贝和浅拷贝 列表存储数据,列表拷贝就是数据备份 浅拷贝 优点:占用内存较少 缺点:修改深层数据,会影响原数据 深拷贝 优点:修改数据,互不影响 缺点:占用内存较大 ""&quo ...