Equal
equals()方法是用来判断其他的对象的引用相等,与==判断值相等有根本不同
定义如下:
public boolean equals(Object obj) {
return (this == obj);
} 有以下特点:
自反性(reflexive)。对于任意不为
null的引用值x,x.equals(x)一定是true。对称性(symmetric)。对于任意不为
null的引用值x和y,当且仅当x.equals(y)是true时,y.equals(x)也是true。传递性(transitive)。对于任意不为
null的引用值x、y和z,如果x.equals(y)是true,同时y.equals(z)是true,那么x.equals(z)一定是true。一致性(consistent)。对于任意不为
null的引用值x和y,如果用于equals比较的对象信息没有被修改的话,多次调用时x.equals(y)要么一致地返回true要么一致地返回false
Hascode
hashCode() 的意思是哈希值, 哈希值是经哈希函数运算后得到的结果,哈希函数能够保证相同的输入能够得到相同的输出(哈希值),但是不能够保证不同的输入总是能得出不同的输出。
定义如下:
public native int hashCode();Equal和Hascode的关系
首先要了解一下java的数据结构存储特点,特别是容器
Java 的容器类被分为 Collection 和 Map 两大类,Collection 又可以进一步分为 List 和 Set。 其中 Map 和 Set 都是不允许元素重复的,严格来说Map存储的是键值对,它不允许重复的键值。
值得注意的是:Map 和 Set 的绝大多数实现类的底层都会用到散列表结构
由于每个对象都自带有 hashCode(),这个 hashCode 将会用作散列表哈希函数的输入,hashCode 经过哈希函数计算后得到哈希值,新对象会根据哈希值,存储到相应的内存的单元。
我们不妨假设两个相同的对象,hashCode() 一定相同
由于相同的输入一定会产生相同的输出,于是如果新对象,和容器中已存在的对象相同,新对象计算出的哈希值就会和已存在的对象的哈希值产生冲突。
然后当两个不相同的对象产生哈希冲突后,我们可以用 equals() 方法进一步判断两个对象是否相同。
总之,如果两个对象是相等的,它们的 equals() 方法应该要返回 true,它们的 hashCode() 需要返回相同的结果。但两个对象的 hashCdoe() 相同,它的 equals() 方法不一定是true
最后
一般来说,重写了equal方法之后也要重写hascode方法,二者是捆绑的,这是一条潜在的原则。hascode的目的是提高程序性能,时间复杂度为常数级别,减少对equal方法的调用(需要遍历)。