1、*为什么要重写equals方法,首先我们来看一下equals源码:
1 public boolean equals(Object anObject) { 2 if (this == anObject) { 3 return true; 4 } 5 if (anObject instanceof String) { 6 String anotherString = (String)anObject; 7 int n = count; 8 if (n == anotherString.count) { 9 char v1[] = value; 10 char v2[] = anotherString.value; 11 int i = offset; 12 int j = anotherString.offset; 13 while (n-- != 0) { 14 if (v1[i++] != v2[j++]) 15 return false; 16 } 17 return true; 18 } 19 } 20 return false; 21 }
*可以看出首先判定的是两个类的地址是否一致,如果是同一个类则地址相同,则符合;
*其次如果比较的两个类是String类则比较他们每个字符是否一致,如果一致则符合;
*可以看出,原来的equals方法并没有给出其他类比较的具体依据,如果两个Person类如果id一直我们则认为相同,
所以持久化时,hibernate会调用equals方法判断两个实体是否相同,即:数据库中两行是否一样,我们必须给出判定方法,原来的equals是不够用的
2、*为什么要重写Hashcode方法,我们任然来看一段代码:
1 import java.util.HashSet; 2 3 public class Test { 4 5 String name; 6 7 public Test(String name) { 8 this.name = name; 9 } 10 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 14 HashSet<Test> hs=new HashSet<Test>(); 15 Test t1=new Test("abc"); 16 Test t2=new Test("abc"); 17 System.out.println(t1.equals(t2)); 18 hs.add(t1); 19 hs.add(t2); 20 System.out.println(hs.size()); 21 } 22 23 @Override 24 public boolean equals(Object obj) { 25 // TODO Auto-generated method stub 26 if (this == obj) 27 return true; 28 else if (obj instanceof Test) { 29 String name = ((Test) obj).name; 30 if (this.name.equals(name)) 31 return true; 32 else 33 return false; 34 } else 35 return false; 36 } 37 38 }
*上面代码运行结果为:
true
2
我们发现当我们重写equals后,破坏了一些Java规则:如果两个对象相等,则不能放到HashSet集合中,但上面的结果恰恰相反,两个对象相等,却任然能放到HashSet中
*由此我们可以看出,放入HashSet集合时,并没有调用equals方法,那HashSet判断两个对象相等调用的是什么方法呢?很显然调用了HashCode方法,当我们重写Hashcode方法后,就会满足上述规则,所以重写equals方法后必须重写hashcode方法;
3、总结:equals和hashcode方法是重两个不同角度判断对象相等的,但前提是他们的效果必须一致:即有一个判断相等,则另一个必须判断为相等;