1. 首先,Java中的equals()和hashCode()这两个方法是从Object类继承过来的
equals()在Object类中的定义如下:
public boolean equals(Object obj){
return(this==obj);
}
可见,在Object类中equals()方法和"=="是一样的概念。equals()方法实际上是对两个对象的地址值进行比较。
2. String类中的equals()方法和hashCode()方法
在String、Math、Integer等这些类中都重写了Object类中的equals()方法和hashCode()方法。暂且不看这些类中对这两个方法得重写代码。在String类中,equals()方法实际是比较两个对象的内容,而不是地址值。在基本类型中,equals()方法还是对值进行比较。
3. Java对equals()方法的要求
• 类推性:如果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是非null对象;x.equals(和x不同类型的对象)永远返回是“false”。
4. hashCode()方法和equals()方法
对于hashCode()方法返回对象的地址值(该值是经过对对象的地址经过hash运算得到的),equals()方法比较的是对象的地址值。但像String这些对Object类中的equals()和hashCode()方法进行重写的类来说就不一样了。
如果两个对象经过equals()方法相等的话,那么他们的hashCode()一定相等;
如果两个对象的hashCode()相等的话,他们经过equals()方法就不一定相等;换句话说,equals()方法不相等的两个对象,hashcode()有可能相等(这有可能是因为对对象地址进行哈希运算的冲突造成的);
说明:equals()方法和hashCode()方法在Object类和String类中都能够使用。equals()方法在Object中比较的是两个对象的地址值,当两个对象的地址值相等时,他们的hashCode()肯定是相等的;在String类中,由于重写了Object类,如果分析String类中的equals()和hashCode()方法的话,就会知道String类中equals比较两个对象的内容,当两个对象的内容相同时,他们的hashCode()也是相等的。
5. Java集合中判断两个对象是否相等的原则
1),判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入2)
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的)
2),判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)
为什么是两条准则,难道用第一条不行吗?不行,因为前面已经说了,hashcode()相等时,equals()方法也可能不等,所以必须用第2条准则进行限制,才能保证加入的为非重复元素。