1 equals方法

Object类中默认的实现方式是  :   return this == obj  。那就是说,只有this 和 obj引用同一个对象,才会返回true。

而我们往往需要用equals来判断 2个对象是否等价,而非验证他们的唯一性。这样我们在实现自己的类时,就要重写equals.

按照约定,equals要满足以下规则。

  • 自反性:  x.equals(x) 一定是true
  • 对null:  x.equals(null) 一定是false
  • 对称性:  x.equals(y)  和  y.equals(x)结果一致
  • 传递性:  a 和 b equals , b 和 c  equals,那么 a 和 c也一定equals。
  • 一致性:  在某个运行时期间,2个对象的状态的改变不会影响equals的决策结果,那么,在这个运行时期间,无论调用多少次equals,都返回相同的结果。

举例:重写equals方法

 1 class Test
 2 {
 3     private int num;
 4     private String data;
 5
 6     public boolean equals(Object obj)
 7     {
 8         if (this == obj)
 9             return true;
10
11         if ((obj == null) || (obj.getClass() != this.getClass()))
12             return false;
13
14         //能执行到这里,说明obj和this同类且非null。
15         Test test = (Test) obj;
16         return num == test.num&& (data == test.data || (data != null && data.equals(test.data)));
17     }
18
19     public int hashCode()
20     {
21         //重写equals,也必须重写hashCode。具体后面介绍。
22     }
23
24 }

2 hashCode方法

这个方法返回对象的散列码,返回值是int类型的散列码。
对象的散列码是为了更好的支持基于哈希机制的Java集合类,例如 Hashtable, HashMap, HashSet 等。

关于hashCode方法,一致的约定是:

  • 在某个运行时期间,只要对象的(字段的)变化不会影响equals方法的决策结果,那么,在这个期间,无论调用多少次hashCode,都必须返回同一个散列码。
  • 如果2个对象通过equals调用后返回是true,那么这个2个对象的has
  • hCode方法也必须返回同样的int型散列码如果2个对象通过equals返回false,他们的hashCode返回的值允许相同。(然而,程序员必须意识到,hashCode返回独一无二的散列码,会让存储这个对象的hashtables更好地工作。)

重写了euqls方法的对象必须同时重写hashCode()方法。

3 为什么必须重写hashCode方法?

在上面的例子中,Test类对象有2个字段,num和data,这2个字段代表了对象的状态,他们也用在equals方法中作为评判的依据。那么, 在hashCode方法中,这2个字段也要参与hash值的运算,作为hash运算的中间参数。这点很关键,这是为了遵守:2个对象equals,那么 hashCode一定相同规则。

也是说,参与equals函数的字段,也必须都参与hashCode 的计算。

4 重写hashCode时注意事项

重写hashCode方法时除了上述一致性约定,还有以下几点需要注意:

(1)返回的hash值是int型的,防止溢出。

(2)不同的对象返回的hash值应该尽量不同。(为了hashMap等集合的效率问题)

(3)《Java编程思想》中提到一种情况

“设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果在讲一个对象用put()添加进HashMap时产生一个hashCdoe值,而用get()取出时却产生了另一个hashCode值,那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码”。

举个例子

public class Test {private int num;private String data;public Test(int num,String data){this.num = num;this.data = data;}public void setNum(int num) {this.num = num;}public boolean equals(Object obj){if (this == obj)return true;if ((obj == null) || (obj.getClass() != this.getClass()))return false;Test test = (Test) obj;return num == test.num&& (data == test.data || (data != null && data.equals(test.data)));}public int hashCode(){int hash = 7;hash = 31*hash+num;hash = 31*hash+data.hashCode();return hash;}public static void main(String[] args) {Map<Test,Integer> map = new HashMap<>();Test t1 = new Test(21,"ouym");map.put(t1, 1);t1.setNum(20);System.out.println(map.get(t1));}}

输出值为null,我的天呐,hashMap取不到值了。

不重写equals和hashCode方法的话是不依赖于对象属性的变化的,也就是说这里使用默认的hashCode方法可以取到值。但是我们重写equal方法的初衷是判定name和num属性都相等的Test对象是相等的,而不是说同一个对象的引用才相等,而num=21和num=20明显不想等,所以这里hashCode返回值不同并不违背设计的初衷。注意上面代码的使用陷阱。

来自:https://www.cnblogs.com/lulipro/p/5628750.html

转载于:https://www.cnblogs.com/ouym/p/8963219.html

为什么重写equals方法时,要求必须重写hashCode方法?相关推荐

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

    推荐阅读: 一线架构师总结SpringBoot,Cloud,Nginx与Docker,不信你搞不懂 47天洒热血复习,我终于"挤进"了字节跳动(附面经+学习笔记) 五年时间,从蘑菇 ...

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

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

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

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

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

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

  5. java方法的调用怎么跳出_JAVA 的一个方法调用另一个方法时,怎么把那个方法里的数据调用出来...

    例如:此例子中Calcute()方法调用dispMax()方法时,怎么把curCost的数据调用到publicListgetBidListByName1(Stringname)中来,,,谢谢大家来帮忙 ...

  6. Java中重写equals()方法时注意点

    Java中重写equals()方法时注意点 一直说,重写一个对象的equals()方法时我们必须重写HashCode()方法,但是如果我们不重写呢?会有什么影响呢? 首先看一下,什么情况下我们需要重写 ...

  7. why在重写equals时还必须重写hashcode方法

    首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anO ...

  8. 为什么重写equals时必须重写hashCode方法?

    2019独角兽企业重金招聘Python工程师标准>>> 首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashco ...

  9. JAVA中重写equals()方法的同时要重写hashcode()方法

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  10. JAVA中list.contains()方法,要重写equals(),hashcode()方法

    今天动力节点java培训机构小编为大家介绍"JAVA中list.contains()方法,要重写equals(),hashcode()方法",希望能够帮助正在学习java的零基础学 ...

最新文章

  1. 阳光学院计算机科学与技术需要英语四级,给各位想报阳光的朋友一点建议!来自学长的亲身经历!...
  2. whea uncorrectable error蓝屏_Windows 10再出“不可选”更新:蓝屏、死机比较烦
  3. Service Broker实现发布-订阅(Publish-Subscribe)框架
  4. 无线 iphone客户端测试白皮书(二)
  5. jeecg 如何重新加载当前渲染tab页面
  6. 从源码角度解释 fragment 坑(一)
  7. C语言 signal
  8. [渝粤教育] 西南科技大学 现代制造系统 在线考试复习资料2021版
  9. AC日记——找最大数序列 openjudge 1.9 10
  10. UnityWebPlayer使用(1) 单机环境下在WinForm中使用Unity3d
  11. C语言库函数源码在线,C语言库函数(包括所有函数)
  12. 五笔打字简明教程(86版)
  13. 10.29 逻辑回归和交差熵
  14. 观李永乐老师讲音律有感——《管子·地员》之“三分损益法”的探究
  15. 《黑客帝国》的宗教启示
  16. elementui的表单验证踩坑-动态绑定输入框required后只显示英文提示
  17. modelsim is exiting with code:211 10秒后自动关闭退出
  18. 【Java】SpringBoot后端格式转换:把Word转成PDF再按页转成图片在前端展示(Linux)
  19. c语言课后答案上海交通,上海交通大学继续教育学院2012春——程序设计(C)作业1(有答案)...
  20. RC延时电路的 时间常数 和 延时时间(电压达到时间)和电容充放电时间计算和选取

热门文章

  1. mysql跳脱字符 单引号_MYSQL特殊字符(单引号,行尾斜杠)的处理
  2. smartforms长文本处理方式
  3. Windows系统单网卡配置双IP双网关
  4. 离散效率写给自己的话 二
  5. java 日期calendar_Java中用Calendar类计算周和周的起始日期(转)
  6. 7天内新闻前加 new
  7. IP设置的批处理文件
  8. PowerBuilder DataWindow 38个开发技巧
  9. Windows7安装PowerShell5.1方法(Flutter新版本需要)
  10. Spring Data JPA根据属性名查询