介绍:

Java Object类提供了方法的基本实现– hashCode()equals()。 这些方法非常有用,尤其是在使用Collection框架时。 哈希表实现依赖于这些方法来存储和检索数据。

在本教程中,我们将学习hashCode()equals()之间的协定它们的默认实现)。 我们还将讨论何时以及如何覆盖这些方法。

默认行为:

首先让我们看一下这些方法的默认实现:

存在于Object类中的equals()方法只是比较对象引用:

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

因此,默认情况下, obj1.equals(obj2)obj1 == obj2相同。

equals()方法比较诸如String等的类的实际值,因为它们在相应的类中被覆盖。

JDK中hashCode()方法的签名为:

public native int hashCode();

在这里, native关键字表示该方法是使用JNI (Java本机接口)以本机代码实现的。

hashCode()方法返回一个int类型。 默认情况下,返回值表示对象存储器地址。

实施原则:

在覆盖equals()hashCode()方法之前,我们先来看一下准则:

1. equals():   我们对equals()方法的实现必须是:

  • 反身:对于任何参考值objobj.equals(obj)应该返回true
  • 对称:对于参考值obj1obj2 ,如果obj1.equals(obj2)true,obj2.equals(obj2)也应返回true
  • 传递性:对于值OBJ1参考,OBJ 2和 OBJ 3,如果obj1.equals(OBJ 2) 真实 ,obj2.equals(OBJ 3) ,那么obj1.equals(OBJ 3)也应该返回true
  • 一致:只要我们没有更改实现, equals()方法的多次调用必须始终返回相同的值

2. hashCode():实现hashCode()时,必须考虑以下几点:

  • 在一次执行中, hashCode()的多次调用必须返回相同的值,前提是我们不更改equals()实现中的属性
  • 相等的对象必须返回相同的hashCode()
  • 两个或更多不相等的对象可以具有相同的hashCode()

尽管在覆盖这些方法时要牢记上述所有原则,但是其中有一个流行的规则:

对于两个对象obj1obj2

  • 如果obj1.equals(obj2),obj1.hashCode()= obj2.hashCode()必须为true
  • 但是,如果obj1.hashCode()== obj2.hashCode() ,则obj1.equals(obj2)可以返回truefalse,即obj1obj2可能相等或不相等

这通常被称为equals()hashCode()契约。

为什么覆盖

hashCode()equals()方法在基于哈希表的实现中存储和检索元素方面起着重要作用。 hashCode()确定给定项映射到的存储桶。 在存储桶中, equals()方法用于查找给定的条目。

假设我们有一个Employee类:

public class Employee {private int id;private String name;//constructors, getters, setters, toString implementations}

还有一个存储Employee作为键的HashMap

Map<Employee, Integer> map = new HashMap<>();map.put(new Employee(1, "Sam"), 1);
map.put(new Employee(2, "Sierra"), 2);

现在我们已经插入了两个条目,让我们尝试一个containsKey()检查:

boolean containsSam = map.containsKey(new Employee(1, "Sam")); //false

尽管我们有Sam的条目,但是containsKey()返回false 。 这是因为我们尚未覆盖equals()hashCode()方法。 默认情况下, equals()只会进行基于引用的比较。

覆盖

根据Javadocs:

当我们覆盖equals()方法时,我们还必须覆盖hashCode()方法。

这将有助于避免违反equals-hashCode合同。

请注意,如果我们违反合同,编译器不会抱怨,但是当我们将此类对象作为键存储在HashMap中时,最终可能会遇到意外行为。

我们可以使用IDE的功能快速覆盖这些方法。 使用Eclipse时,我们可以转到Source-> Generate hashCode()和equals()。 让我们看看为Employee类生成的实现:

public class Employee {...@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + id;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Employee other = (Employee) obj;if (id != other.id)return false;if (name == null) {if (other.name != null)return false;} else if(!name.equals(other.name))return false;return true;}
}

显然,相同的字段已用于实现equals()hashCode()方法,以与合同保持一致。

最佳做法:

使用equals()hashCode()时应遵循的一些最佳实践包括:

  • 实现hashCode()以在各个存储桶之间平均分配项目。 这样做的目的是最大程度地减少碰撞次数,从而获得良好的性能
  • 对于equals()hashCode()实现,我们应该使用相同的字段
  • HashMap中将不可变对象作为键,因为它们支持缓存哈希码值
  • 使用ORM工具时,请始终使用getter代替hashCode()equals()方法定义中的字段。 那是因为有些字段可能是延迟加载的

结论:

在本教程中,我们首先研究了equals()hashCode()方法的默认实现。 稍后,我们讨论了何时以及如何覆盖这些方法。

成为第一个发表评论的人。

翻译自: https://www.javacodegeeks.com/2019/05/java-equals-hashcode.html

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

  1. 搞懂 Java equals 和 hashCode 方法

    搞懂 Java equals 和 hashCode 方法 分析完 Java List 容器的源码后,本来想直接进入 Set 和 Map 容器的源码分析,但是对于这两种容器,内部存储元素的方式的都是以键 ...

  2. 理解Java中的hashCode 和 equals 方法

    2019独角兽企业重金招聘Python工程师标准>>> 在Java里面所有的类都直接或者间接的继承了java.lang.Object类,Object类里面提供了11个方法,如下: 1 ...

  3. 程序猿的日常——Java基础之equals与hashCode

    equals和hashCode是我们日常开发最常使用的方法,但是因为一般都使用默认的规则,因此也很少会引起关注.不过了解他们的用途和设计的原则,还是会帮助我们更好的设计代码. equals equal ...

  4. Java的equals() 和 hashCode()

    2019独角兽企业重金招聘Python工程师标准>>> 首先,equals()方法和hashCode()方法都来自于Object类的定义,Java类都继承了这两个方法,都定义了自己的 ...

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

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

  6. Java基础提升篇:equals()与hashCode()方法详解

    概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) public int hashCode() Object类是类继承 ...

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

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

  8. Java双等号,Equals(),HashCode()小结

    默认情况 - 双等号==,比较的是内存地址. - equals(),默认比较的是内存地址. - hashCode(),默认返回的是object的内存地址. String中方法改写的情况 经常会遇到需要 ...

  9. java equals重写原则_java中为何重写equals时必须重写hashCode方法详解

    前言 大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 在上一篇博文Ja ...

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

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

最新文章

  1. 解决Oracle启动失败
  2. C++中类的静态成员变量和静态成员函数
  3. php隐藏文件链接,php隐藏文件实际下载地址的方法
  4. win10浏览器_Win10系统中ie浏览器的证书错误应该如何解决?
  5. docker启动失败,报docker dead but pid file exists,处理方式
  6. git 提示 error setting certificate verify locations !解决
  7. Java面向对象编程(高级)
  8. c语言 typedef_C Typedef-能力倾向问题与解答
  9. Java教程:Java String字符串和整型int的相互转换
  10. pandas.Series.values
  11. Crash Course经济学笔记
  12. USB转TTL、USB转232的区别
  13. Guitar Pro8最新2023中文免费吉他乐谱作曲练习工具
  14. Android Google地图接入(一)
  15. CS0012 错误。必须添加对程序集”xxxxx,Version=4.0.0.0,Culture=neutral,PublicKeyToken=xxxxxxx“的引用
  16. spotify能免费下歌吗_Spotify免费版与高级版:值得升级吗?
  17. 什么时候要把方法写成静态的。什么时候写成实例化方法。
  18. 使用Scrapy框架爬取88读书网小说,并保存本地文件
  19. 算法基础之二叉树理论
  20. xp 两个计算机互访,XP和Windows7文件不能互访解决办法

热门文章

  1. codeforces 877F F. Ann and Books hash+莫队算法
  2. 2017年秋招美团Java程序员开发,看我如何拿到offer
  3. 漫画:什么是计数排序
  4. 影响程序员生涯的三个错误观念,你千万不要犯
  5. 架构师之路:从码农到架构师你差了哪些
  6. 修改Tomcat编码方式的两种方法
  7. java之正则表达式
  8. C#中的序列化和反序列化
  9. 实体类为什么要用包装类而不用基本类型
  10. linux将光驱挂载到目录下,Linux操作系统下关于光驱的挂载