hashcode()与equals()

摘自java api总原文

hashCode()
public int hashCode()
返回对象的哈希码值。 支持这种方法是为了散列表,如HashMap提供的那样 。
hashCode的总合同是:

只要在执行Java应用程序时多次在同一个对象上调用该方法, hashCode方法必须始终返回相同的整数,前提是修改了对象中equals比较中的信息。 该整数不需要从一个应用程序的执行到相同应用程序的另一个执行保持一致。
如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
不要求如果两个对象根据equals(java.lang.Object)方法不相等,那么在两个对象中的每个对象上调用hashCode方法必须产生不同的整数结果。 但是,程序员应该意识到,为不等对象生成不同的整数结果可能会提高哈希表的性能。
尽可能多的合理实用,由类别Object定义的hashCode方法确实为不同对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java的编程语言不需要此实现技术。)

结果
该对象的哈希码值。
equals()
public boolean equals(Object obj)
指示一些其他对象是否等于此。
equals方法在非空对象引用上实现等价关系:

自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。
它是对称的 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报true 。
传递性 :对于任何非空引用值x , y和z ,如果x.equals(y)回报true和y.equals(z)回报true ,然后x.equals(z)应该返回true 。
它是一致的 :对于任何非空引用值x和y ,多次调用x.equals(y)始终返回true或始终返回false ,没有设置中使用的信息equals比较上的对象被修改。
对于任何非空的参考值x , x.equals(null)应该返回false 。
该equals类方法Object实现对象上差别可能性最大的相等关系; 也就是说,对于任何非空的参考值x和y ,当且仅当x和y引用相同的对象( x == y具有值true )时,该方法返回true 。

请注意,无论何时覆盖该方法,通常需要覆盖hashCode方法,以便维护hashCode方法的通用合同,该方法规定相等的对象必须具有相等的哈希码。

参数
obj - 与之比较的参考对象。
结果
true如果此对象与obj参数相同; false否则。

如果要覆盖Object的equals的方法,一定要满足以下几个等价关系:
1)自反性,对于任何非null的引用值x,x.equals(x)必须反回true
2)对称性,对于任何非null的引用值x,y,当且仅当y.equals(x)返回true时,x.equals(y),才返回true.
3)传递性,对于任何非null的引用值x,y,z,如果x.equals(y)返回true,并且y.equals(z)返回ture,那
么x.equals(z)也必须返回true.
4)一致性,对于任何非null的引用值x,y,只要equals比较操作的两个对象中所用的信息没有被修改,多次
调用x.equals(y)就会一致的返回true,或者一致的返回false.
对于任何的非null的值x,x.equals(null),必须返回false .

也就是当我们写了一个自己的class,然后用class new了两个对象,如果在这两个对象上用equals时,此时比较的两个引用是不是一样,也就是他们的物理地址是不是一样,如果不一样的话,就会返回false.

Student stu = new Student();
stu.setId(1);
stu.setUsername("xiaowang");
Student stu2 = new Student();
stu2.setId(1);
stu2.setUsername("xiaowang");
System.out.println(stu.equals(stu2));
// 输出false

了解hashcode算法的话你会明白,即使hashcode相同值也有可能不同!那么,就需要我们重写这两个方法
而且我们实际用的时候,往往不是希望比较两个对象的物理地址是不是一样,而比较两个对象的属性等东西是不是一样,所以Object提供的方法往往不能满足我们要求。

重写equals()

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
Student other = (Student) obj;
if (id != other.id)
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
//在来执行上面的代码,输出结果为:true