为什么重写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 ...
随机推荐
- 菜鸡的Java笔记 第二十二 - java 对象多态性
本次只是围绕着多态性的概念来进行讲解,但是所讲解的代码与实际的开发几乎没有关系,而且多态一定是在继承性的基础上才可以操作的, 而本次将使用类继承的关系来描述多态的性质,实际的开发中不会出 ...
- [luogu7600]封闭道路
对于确定的$K$,问题也可以看作每一个点最多选$K$条出边,并最大化选择的边权和 关于这个问题,有如下的树形dp-- 令$f_{k,0/1}$表示以$k$为根的子树中,根节点选择不超过$K/K-1$个 ...
- [cf1486F]Pairs of Paths
以1为根建树,先将所有路径挂在lca上,再分两类讨论: 1.lca相同,此时我们仅关心于lca上不经过第$a$和$b$个儿子路径数,容斥一下,即所有路径-经过$a$的-经过$b$的+经过$a$和$b$ ...
- [atARC070F]HonestOrUnkind
考虑当$a\le b$时,构造两种方案,满足诚实的人不交,接下来要求对于任意询问,这两种方案的答案都有可能相同 考虑询问$(i,j)$,若$i$在两种方案中有一种不诚实,那么总可以让答案相同,又因为诚 ...
- [bzoj1222]产品加工
用f[i][j]表示完成前i个任务,在A机器上加工j小时时B机器上最少要工作多小时,转移就分为三种,即$f[i][j]=min(f[i-1][j-t1],f[i-1][j]+t2,f[i-t3]+t3 ...
- [SQL Server]一列多行转换为字符串
在 SQL Server 中,如何将多行数据变成一个字符串保存. skill 投石 挖矿 刮痧 上面三行数据想要得到结果为:投石,挖矿,刮痧 有两种方式: 拼接字符串. 使用 for XML 首先创建 ...
- Vue 中使用 TypeScript axios 使用方式
Vue 中使用 TypeScript axios 使用方式 方式一 import axios from 'axios'; Vue.prototype.$axios = axios; // 在 .vue ...
- perl 子函数传入多个数组
perl中的引用和C中的指针一样,用"\"标识,引用后可使用符号"->"取值.解引用则在对应的数据类型前加$,@ 或%. 这里这里用两数组求和做示例,引用 ...
- mysql—mysql错误Every derived table must have its own alias解决
Every derived table must have its own alias 这句话的意思是说每个派生出来的表都必须有一个自己的别名. 一般在多表查询时,会出现此错误. 因为,进行嵌套查询的 ...
- oracle中char],varchar,varchar2
VARCHAR.VARCHAR2.CHAR的区别 1.CHAR的长度是固定的,而VARCHAR2的长度是可以变化的, 比如,存储字符串"abc",对于CHAR (20),表示你存储 ...