java equals 与 hashCode
转:http://m.blog.csdn.net/blog/pengchua/2297547#
如果你为某个类写了equals方法,那么应该同时编写hashCode方法.
如果没有提供hashcode方法,编译器不会报错,而且也可能不会遇到任何问题.但是将对象插入到
基于冲突的哈希表(类java.util.Set也使用同样的哈希表实现)可能导致不可预料的后果.解决产生的问题,
可能要花费大量的时间.所以一定要养成这样的习惯:如果编写了方法equals,同时也提供相应的hashcode方法
equals():
它是用于进行两个对象的比较的,是对象内容的比较。
对象内容的比较才是设计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()所返回的值是用来分类对象在一些特定的Collection对象中的位置。这些对象是
HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须自己设计,用来
协助HashMap, Hashtable, HashSet,等等对自己所收集的大量对象进行搜寻和定位。
这些Collection对象究竟如何工作的,想象每个元对象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。但是一个
元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。
当一个对象类型作为Collection型对象的元对象时,这个对象应该拥有自己处理equals(),和/
或处理hashCode()的设计,而且要遵守前面所说的两种原则。equals()先要查null和是否是同
一类型。查同一类型是为了避免出现ClassCastException这样的异常给丢出来。查 null是为了
避免出现NullPointerException这样的异常给丢出来。