2019独角兽企业重金招聘Python工程师标准>>>

首先,equals()方法和hashCode()方法都来自于Object类的定义,Java类都继承了这两个方法,都定义了自己的实现。

equals:

equlas()方法的正确理解应该是:判断两个对象是否相等。那么判断对象相等的标尺又是什么?

在object类中,此标尺即为==。

public boolean equals(Object obj) {return (this == obj);}

当然,这个标尺不是固定的,其他类中可以按照实际的需要对此标尺含义进行重定义。如String类中则是依据字符串内容是否相等来重定义了此标尺含义。

  public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String) anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}

如此可以增加类的功能性和实际编码的灵活性。当然了,如果自定义的类没有重写equals()方法来重新定义此标尺,那么默认的将是其父类的equals(),直到Object基类。

如下场景的实际业务需求,对于User bean,由实际的业务需求可知当属性uid相同时,表示的是同一个User,即两个User对象相等。则可以重写equals以重定义User对象相等的标尺。

package com.corn.objectsummary;public class User {private int uid;private String name;private int age;public int getUid() {return uid;}public void setUid(int uid) {this.uid = uid;}protected String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic boolean equals(Object obj) {if (obj == null || !(obj instanceof User)) {return false;}if (((User) obj).getUid() == this.getUid()) {return true;}return false;}
}
package com.corn.objectsummary;public class ObjectTest implements Cloneable {public static void main(String[] args) {User u1 = new User();u1.setUid(111);u1.setName("张三");User u2 = new User();u2.setUid(111);u2.setName("张三丰");System.out.println(u1.equals(u2)); //返回true}}

ObjectTest中打印出true,因为User类定义中重写了equals()方法,这很好理解,很可能张三是一个人小名,张三丰才是其大名,判断这两个人是不是同一个人,这时只用判断uid是否相同即可。

重写equals()方法遵循的准则:

  • 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。

  • 反射性:x.equals(x)必须返回是“true”。

  • 类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。

  • 还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。

  • 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

如上重写equals方法表面上看上去是可以了,实则不然。因为它破坏了Java中的约定:重写equals()方法必须重写hasCode()方法。

hashCode:

hashCode():方法返回一个整形数值,表示该对象的哈希码值。

hashCode()具有如下约定:

1).在Java应用程序程序执行期间,对于同一对象多次调用hashCode()方法时,其返回的哈希码是相同的,前提是将对象进行equals比较时所用的标尺信息未做修改。在Java应用程序的一次执行到另外一次执行,同一对象的hashCode()返回的哈希码无须保持一致;

2).如果两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等;

3).反之,两个对象调用hasCode()返回的哈希码相等,这两个对象不一定相等。

即严格的数学逻辑表示为: 两个对象相等 <=>  equals()相等  => hashCode()相等。因此,重写equlas()方法必须重写hashCode()方法,以保证此逻辑严格成立,同时可以推理出:hasCode()不相等 => equals()不相等 <=> 两个对象不相等。

可能有人在此产生疑问:既然比较两个对象是否相等的唯一条件(也是次要条件)是equals,那么为什么还要弄出一个hashCode(),并且进行如此约定,弄得这么麻烦?

其实,这主要体现在hashCode()方法的作用上,其主要用于增强哈希表的性能。

以集合类中,以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode()方法,需要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。通过借助于hasCode方法,先计算出即将新加入对象的哈希码,然后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象即可。(注:Set的底层用的是Map的原理实现)

在此需要纠正一个理解上的误区:对象的hashCode()返回的不是对象所在的物理内存地址。甚至也不一定是对象的逻辑地址,hashCode()相同的两个对象,不一定相等,换言之,不相等的两个对象,hashCode()返回的哈希码可能相同。

因此,在上述代码中,重写了equals()方法后,需要重写hashCode()方法。

package com.corn.objectsummary;public class User {private int uid;private String name;private int age;public int getUid() {return uid;}public void setUid(int uid) {this.uid = uid;}protected String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic boolean equals(Object obj) {if (obj == null || !(obj instanceof User)) {return false;}if (((User) obj).getUid() == this.getUid()) {return true;}return false;}@Overridepublic int hashCode() {int result = 17;result = 31 * result + this.getUid();return result;}
}

注:上述hashCode()的重写中出现了result*31,是因为result*31 = (result<<5) - result。之所以选择31,是因为左移运算和减运算计算效率远大于乘法运算。当然,也可以选择其他数字。

转载于:https://my.oschina.net/u/2433960/blog/884316

Java的equals() 和 hashCode()相关推荐

  1. Java实战equals()与hashCode()

    2019独角兽企业重金招聘Python工程师标准>>> 一.equals()方法详解 equals()方法在object类中定义如下: 代码 public boolean equal ...

  2. Java:重写equals()和hashCode()

    http://blog.csdn.net/ansel13/article/details/5437486 很基础的东西就是由于没上心,三番五次地出错,这次好好总结下吧. 众所周之,String .Ma ...

  3. Java:重写equals()和hashCode() 1

    來源: 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://zhangjunhd.blog.51cto.com/113473 ...

  4. hashCode之二--Java:重写equals()和hashCode()

    以下内容总结自<Effective Java>. 1.何时需要重写equals() 当一个类有自己特有的"逻辑相等"概念(不同于对象身份的概念). 2.设计equals ...

  5. 学习Java编程equals()和hashCode()方法

    equals()和hashCode()区别? equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. hashCode():计算出对象实例的哈希 ...

  6. java中equals,hashcode和==的区别

    原文地址http://blog.csdn.net/hla199106/article/details/46907725 1.== java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型 ...

  7. java基础 equals与hashCode

    Java中equals相关 目录 Java中equals相关 equals()与==的关系 equals()和hashCode() hashCode()介绍 hashCode()的意义 hashCod ...

  8. 有关java中equals()与hashCode()的探讨

    参考文章:从一道面试题彻底搞懂hashCode与equals的作用与区别及应当注意的细节--感谢原博主 先上栗子 Student student1 = new Student();Student st ...

  9. Java重写equals()和hashCode()

    1.何时需要重写equals() 当一个类有自己特有的 "逻辑相等"概念(不同于对象身份的概念). 2.设计equals() [1]使用instanceof操作符检查 " ...

最新文章

  1. 基础通俗讲解集成学习算法
  2. 梯度下降算法的正确步骤是什么?
  3. Linux内核探讨-- 第二章
  4. tab 页形式展现多张报表
  5. c#Clay开源的动态语言dynamic框架,让您形如javascript的方式创建对象!
  6. 鸿蒙生态与苹果生态有什么区别,华为想用鸿蒙统一生态,苹果直接用芯片大一统,走到华为前面?...
  7. java for 面试题_Java面试题整理
  8. CDH秘籍(两):cloudera Manager存储监控数据
  9. 电影下载地址大集合,只要是电影就能找到
  10. CSF文件格式播放器
  11. 目前可行的4种知网文献免费下载方法分享
  12. 一文总结图像生成必备经典模型(二)
  13. 窗口特征(Window Features)
  14. kali 配置静态ip的坑
  15. JAVA 实现《捕鱼达人》游戏
  16. 韵达快递单号可以批量查询吗
  17. 吴恩达机器学习笔记(七)神经网络:代价函数
  18. C++循环结构实例:估算e值:计算e=1+(1/1!)+(1/2!)+…的近似值,1/n!小于10^(-7)时停止计算
  19. 奇梦达产能削减四分之三
  20. python俄罗斯方块编程思路_python游戏开发之俄罗斯方块(一):简版

热门文章

  1. PHP中include()与require()的区别说明
  2. Android Wear开发 - 数据通讯 - 第二节 : 数据的发送与接收
  3. nginx0.8 + php-5.3.4 + memcached
  4. 给Visual Studio 2010中文版添加Windows Phone 7模板
  5. 数据中心网络架构 — 云数据中心网络 — 新型叶脊二层网络架构
  6. OpenShift — Overview
  7. 5G — 3 大场景、8 大 KPI
  8. 用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四
  9. LTE voice centric和data centric
  10. NR 5G 关于gNB-CU和gNB-DU