解析Java对象的equals()和hashCode()的使用函数
前言编码
在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是本身设计其中一个,就要设计另一个。在多数状况 下,这两个函数是不用考虑的,直接使用它们的默认设计就能够了。可是在一些状况下,这两个函数最好是本身设计,才能确保整个程序的正常运行。最多见的是当 一个对象被加入收集对象(collection object)时,这两个函数必须本身设计。更细化的定义是:若是你想将一个对象A放入另外一个收集对象B里,或者使用这个对象A为查找一个元对象在收集对 象B里位置的钥匙,并支持是否容纳,删除收集对象B里的元对象这样的操做,那么,equals()和hashCode()函数必须开发者本身定义。其余情 况下,这两个函数是不须要定义的。spa
equals():.net
它是用于进行两个对象的比较的,是对象内容的比较,固然也能用于进行对象参阅值的比较。什么是对象参阅值的比较?就是两个参阅变量的值得比较,咱们 都知道参阅变量的值其实就是一个数字,这个数字能够当作是鉴别不一样对象的代号。两个对象参阅值的比较,就是两个数字的比较,两个代号的比较。这种比较是默 认的对象比较方式,在Object这个对象中,这种方式就已经设计好了。因此你也不用本身来重写,浪费没必要要的时间。设计
对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求以下,这些要求是必须遵循的。不然,你就不应浪费时间:对象
hashCode():
这 个函数返回的就是一个用来进行赫希操做的整型代号,请不要把这个代号和前面所说的参阅变量所表明的代号弄混了。后者不只仅是个代号还具备在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的收集对象中的位置。这些对象是HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须本身设计,用来协助HashMap, Hashtable, HashSet,等等对本身所收集的大量对象进行搜寻和定位。
这些收集对象究竟如何工做的,想象每一个元对象hashCode是一个箱子的 编码,按照编码,每一个元对象就是根据hashCode()提供的代号纳入相应的箱子里。全部的箱子加起来就是一个HashSet,HashMap,或 Hashtable对象,咱们须要寻找一个元对象时,先看它的代码,就是hashCode()返回的整型值,这样咱们找到它所在的箱子,而后在箱子里,每 个元对象都拿出来一个个和咱们要找的对象进行对比,若是两个对象的内容相等,咱们的搜寻也就结束。这种操做须要两个重要的信息,一是对象的 hashCode(),还有一个是对象内容对比的结果。
hashCode()的返回值和equals()的关系以下:blog
为何这两个规则是这样的,缘由其实很简单,拿HashSet来讲吧,HashSet能够拥有一个或更多的箱子,在同一个箱子中能够有一个 或更多的独特元对象(HashSet所容纳的必须是独特的元对象)。这个例子说明一个元对象能够和其余不一样的元对象拥有相同的hashCode。可是一个 元对象只能和拥有一样内容的元对象相等。因此这两个规则必须成立。
设计这两个函数所要注意到的:
若是你设计的对象类型并不使用于收集性对象,那么没有必要本身再设计这两个函数的处理方式。这是正确的面向对象设计方法,任何用户一时用不到的功能,就先不要设计,以避免给往后功能扩展带来麻烦。内存
若是你在设计时想别出心裁,不遵照以上的两套规则,那么劝你仍是不要作这样想入非非的事。我尚未遇到过哪个开发者和我说设计这两个函数要违背前面说的两个规则,我碰到这些违反规则的状况时,都是做为设计错误处理。开发
当一个对象类型做为收集型对象的元对象时,这个对象应该拥有本身处理equals(),和/或处理hashCode()的设计,并且要遵照前面所说 的两种原则。equals()先要查null和是不是同一类型。查同一类型是为了不出现ClassCastException这样的异常给丢出来。查 null是为了不出现NullPointerException这样的异常给丢出来。get
若是你的对象里面容纳的数据过多,那么这两个函数 equals()和hashCode()将会变得效率低。若是对象中拥有没法serialized的数据,equals()有可能在操做中出现错误。想象 一个对象x,它的一个整型数据是transient型(不能被serialize成二进制数据流)。然而equals()和hashCode()都有依靠 这个整型数据,那么,这个对象在serialization以前和以后,是否同样?答案是不同。由于serialization以前的整型数据是有效的 数据,在serialization以后,这个整型数据的值并无存储下来,再从新由二进制数据流转换成对象后,二者(对象在serialization 以前和以后)的状态已经不一样了。这也是要注意的。
转自:http://blog.csdn.net/richardsundusky/article/details/1508028