解析Java对象的equals()和hashCode()的使用

转载 2011年07月20日 11:23:04

解析Java对象的equals()和hashCode()的使用

前言

在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况 下,这两个函数是不用考虑的,直接使用它们的默认设计就可以了。但是在一些情况下,这两个函数最好是自己设计,才能确保整个程序的正常运行。最常见的是当 一个对象被加入收集对象(collection object)时,这两个函数必须自己设计。更细化的定义是:如果你想将一个对象A放入另一个收集对象B里,或者使用这个对象A为查找一个元对象在收集对 象B里位置的钥匙,并支持是否容纳,删除收集对象B里的元对象这样的操作,那么,equals()和hashCode()函数必须开发者自己定义。其他情 况下,这两个函数是不需要定义的。

equals():

它是用于进行两个对象的比较的,是对象内容的比较,当然也能用于进行对象参阅值的比较。什么是对象参阅值的比较?就是两个参阅变量的值得比较,我们 都知道参阅变量的值其实就是一个数字,这个数字可以看成是鉴别不同对象的代号。两个对象参阅值的比较,就是两个数字的比较,两个代号的比较。这种比较是默 认的对象比较方式,在Object这个对象中,这种方式就已经设计好了。所以你也不用自己来重写,浪费不必要的时间。

对象内容的比较才是设计equals()的真正目的,Java语言对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”。
hashCode():
这 个函数返回的就是一个用来进行赫希操作的整型代号,请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的收集对象中的位置。这些对象是HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须自己设计,用来协助HashMap, Hashtable, HashSet,等等对自己所收集的大量对象进行搜寻和定位。

这些收集对象究竟如何工作的,想象每个元对象hashCode是一个箱子的 编码,按照编码,每个元对象就是根据hashCode()提供的代号归入相应的箱子里。所有的箱子加起来就是一个HashSet,HashMap,或 Hashtable对象,我们需要寻找一个元对象时,先看它的代码,就是hashCode()返回的整型值,这样我们找到它所在的箱子,然后在箱子里,每 个元对象都拿出来一个个和我们要找的对象进行对比,如果两个对象的内容相等,我们的搜寻也就结束。这种操作需要两个重要的信息,一是对象的 hashCode(),还有一个是对象内容对比的结果。

hashCode()的返回值和equals()的关系如下:
  • 如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
  • 如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。


为什么这两个规则是这样的,原因其实很简单,拿HashSet来说吧,HashSet可以拥有一个或更多的箱子,在同一个箱子中可以有一个 或更多的独特元对象(HashSet所容纳的必须是独特的元对象)。这个例子说明一个元对象可以和其他不同的元对象拥有相同的hashCode。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。

设计这两个函数所要注意到的:
如果你设计的对象类型并不使用于收集性对象,那么没有必要自己再设计这两个函数的处理方式。这是正确的面向对象设计方法,任何用户一时用不到的功能,就先不要设计,以免给日后功能扩展带来麻烦。

如果你在设计时想别出心裁,不遵守以上的两套规则,那么劝你还是不要做这样想入非非的事。我还没有遇到过哪一个开发者和我说设计这两个函数要违背前面说的两个规则,我碰到这些违反规则的情况时,都是作为设计错误处理。

当一个对象类型作为收集型对象的元对象时,这个对象应该拥有自己处理equals(),和/或处理hashCode()的设计,而且要遵守前面所说 的两种原则。equals()先要查null和是否是同一类型。查同一类型是为了避免出现ClassCastException这样的异常给丢出来。查 null是为了避免出现NullPointerException这样的异常给丢出来。

如果你的对象里面容纳的数据过多,那么这两个函数 equals()和hashCode()将会变得效率低。如果对象中拥有无法serialized的数据,equals()有可能在操作中出现错误。想象 一个对象x,它的一个整型数据是transient型(不能被serialize成二进制数据流)。然而equals()和hashCode()都有依靠 这个整型数据,那么,这个对象在serialization之前和之后,是否一样?答案是不一样。因为serialization之前的整型数据是有效的 数据,在serialization之后,这个整型数据的值并没有存储下来,再重新由二进制数据流转换成对象后,两者(对象在serialization 之前和之后)的状态已经不同了。这也是要注意的。

对象的比较及hashCode、equals方法的使用

如何进行对象的值的比较呢?如String类型的变量,是靠调用equals方法来比较的,而其它的类似数组或普通的对象直接调用equals方法一般是不可以的,这是因为String类型的变量通过调用equa...
  • dfb198998
  • dfb198998
  • 2015-08-18 09:47:06
  • 1149

equals 跟hashcode 在集合中的一点知识点

1、equals方法用于比较对象的内容是否相等(覆盖以后) 2、hashcode方法只有在集合中用到 3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较...
  • lafengwnagzi
  • lafengwnagzi
  • 2016-12-26 22:22:59
  • 667

java Object对象中hashCode和equals方法学习

学习了多年的java的人对hashCode和equals方法都不是很清楚。 总的来说,Java中的集合(Collection)有两类,一类是List,另一类是Set。前者集合内的元素是有序的,元素可以...
  • lan12334321234
  • lan12334321234
  • 2017-04-11 10:45:43
  • 820

Java常考面试题6 equals相同的对象对于的hashCode是否相等?

equals和hashcode的关系
  • HZ_LIZX
  • HZ_LIZX
  • 2017-02-09 17:49:00
  • 2855

java.lang.Object 对象中 hashCode 和 equals 方法详解及其延伸

什么是hashcode hashcode在Java中的相关引用 equals方法 hashcode于equals两者关系比较
  • qq_21163061
  • qq_21163061
  • 2017-06-22 16:21:53
  • 743

HashMap中的equals和hashCode

Java的Object对象有9个方法,其中的equals()和hashCode()在hashMap的实现里面起着比较重要的作用,我在研究hashMap的源码时就遇到了它们俩,此篇博文主要是为了记录它们...
  • qiuych3
  • qiuych3
  • 2016-05-06 21:26:05
  • 1894

HashSet的对象必须实现hashCode()和equals()

java中hashset跟对象重载的equals和hashcode方法到底有什么关系? 以下面里面分析: import java.util.HashSet; publ...
  • sanjiaozhen
  • sanjiaozhen
  • 2015-09-30 01:58:12
  • 2268

Java-正确使用equals和hashCode方法

基本摘抄自Java 中正确使用 hashCode 和 equals 方法 hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个...
  • qing0706
  • qing0706
  • 2016-01-27 14:09:43
  • 2106

JAVA中自定义对象比较时重写equals()方法的同时要重写hashcode()方法

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

对象重写equals时为什么也要重写hashCode方法

Java对于eqauls方法和hashCode方法是这样规定的: a、如果两个对象相同,那么它们的hashCode值一定要相同;b、如果两个对象的hashCode相同,它们并不一定相同。 1、于...
  • shangyadongze
  • shangyadongze
  • 2015-01-19 14:39:55
  • 1095
收藏助手
不良信息举报
您举报文章:解析Java对象的equals()和hashCode()的使用
举报原因:
原因补充:

(最多只允许输入30个字)