1. 程式人生 > >Hibernate中為什麼要重寫equals()和hashCode()這兩個方法

Hibernate中為什麼要重寫equals()和hashCode()這兩個方法

學到Hibernate的多對一對映,書上列舉的例子是多個訂單(Order)對應一個客戶(Customer)對應,同時提到在Hibernate中通過比較兩個持久化物件的識別符號屬性值(ID)來判斷二者是否相等,這就需要重寫實體類的equals()方法和hashCode()方法。

在網上查了一下資料,然後自己除錯了一下,頗有收穫,整理如下:

equals()和hashCode()這兩個方法屬於Object類,而Object類是所有類的父類,因此所有的類都繼承了這兩個方法。其中有一些類重寫了這兩個方法。

例如:Object類的equals()方法程式碼如下:

  1. publicboolean equals(Object obj) {  
  2.     return (this == obj);  
  3.     }  

而String類的equals()方法程式碼如下:

  1. publicboolean equals(Object anObject) {  
  2.     if (this == anObject) {  
  3.         returntrue;  
  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.             returnfalse
    ;  
  16.         }  
  17.         returntrue;  
  18.         }  
  19.     }  
  20.     returnfalse;  
  21.     }  

可以看到,Object類的equals()方法的判斷依據是引用地址,而String類的equals()方法則是在此基礎上加了另一個IF判斷,判斷兩個字串裡的字元是否對應相等。即如果兩個字串變數的引用地址不同,但是是同一個字串的話,這兩個字串被視為相等。

因此通過重寫equals()方法可以按照自己的意願指定判定兩個物件是否相等的依據。

hashCode()方法的作用是返回指定物件的雜湊值。

在集合類(HashMap,HashSet等)中判斷兩個物件是否相等有如下規則:

如果兩個物件雜湊值不同,那麼這兩個物件不相等。如果相同,則呼叫equals()方法判斷,如果equals()方法返回true,則這兩個物件相等,否則不相等。

當equals方法返回值為true時,兩個物件的hashCode值必定相等。

當equals方法返回值為false時,兩個物件的hashCode值不一定不同。

如果重寫了equals()方法,就必須重寫hashCode()方法。

具體的原因可以參照這篇文章:

http://blog.csdn.net/michaellufhl/article/details/5833188

講解的非常透徹,不在此贅述了。

下面解釋在Hibernate中為什麼要在實體類中重寫equals()方法和hashCode()方法

在多對一對映中用HashSet來存放訂單物件(Order)

兩張資料庫表如下:


兩個實體類:

Customer類如下:

  1. package pojo;  
  2. import java.io.Serializable;  
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5. publicclass Customer implements Serializable{  
  6.     private Integer id;  
  7.     private String userName;  
  8.     private String password;  
  9.     private String realName;  
  10.     private String address;  
  11.     private String mobile;  
  12.     private Set<Order> orders=new HashSet<Order>(0);  
  13.     public Set<Order> getOrders() {  
  14.         return orders;  
  15.     }  
  16.     publicvoid setOrders(Set<Order> orders) {  
  17.         this.orders = orders;  
  18.     }  
  19.     public Customer(String userName,String password,String realName,  
  20.             String address,String mobile)  
  21.     {  
  22.         this.userName=userName;  
  23.         this.password=password;  
  24.         this.realName=realName;  
  25.         this.address=address;  
  26.         this.mobile=mobile;  
  27.     }  
  28.     public Customer()  
  29.     {  
  30.     }  
  31.     public Integer getId() {  
  32.         return id;  
  33.     }  
  34.     publicvoid setId(Integer id) {  
  35.         this.id = id;  
  36.     }  
  37.     public String getUserName() {  
  38.         return userName;  
  39.     }  
  40.     publicvoid setUserName(String userName) {  
  41.         this.userName = userName;  
  42.     }  
  43.     public String getPassword() {  
  44.         return password;  
  45.     }  
  46.     publicvoid setPassword(String password) {  
  47.         this.password = password;  
  48.     }  
  49.     public String getRealName() {  
  50.         return realName;  
  51.     }  
  52.     publicvoid setRealName(String realName) {  
  53.         this.realName = realName;  
  54.     }  
  55.     public String getAddress() {  
  56.         return address;  
  57.     }  
  58.     publicvoid setAddress(String address) {  
  59.         this.address = address;  
  60.     }  
  61.     public String getMobile() {  
  62.         return mobile;  
  63.     }  
  64.     publicvoid setMobile(String mobile) {  
  65.         this.mobile = mobile;  
  66.     }  
  67.     //重寫hashCode方法
  68.     @Override
  69.     publicint hashCode()  
  70.     {  
  71.         finalint prime=