Hibernate中為什麼要重寫equals()和hashCode()這兩個方法
學到Hibernate的多對一對映,書上列舉的例子是多個訂單(Order)對應一個客戶(Customer)對應,同時提到在Hibernate中通過比較兩個持久化物件的識別符號屬性值(ID)來判斷二者是否相等,這就需要重寫實體類的equals()方法和hashCode()方法。
在網上查了一下資料,然後自己除錯了一下,頗有收穫,整理如下:
equals()和hashCode()這兩個方法屬於Object類,而Object類是所有類的父類,因此所有的類都繼承了這兩個方法。其中有一些類重寫了這兩個方法。
例如:Object類的equals()方法程式碼如下:
- publicboolean equals(Object obj) {
- return (this == obj);
- }
而String類的equals()方法程式碼如下:
- publicboolean equals(Object anObject) {
- if (this == anObject) {
- returntrue;
- }
- if (anObject instanceof String) {
- String anotherString = (String)anObject;
- int n = count;
- if (n == anotherString.count) {
- char v1[] = value;
- char v2[] = anotherString.value;
- int i = offset;
- int j = anotherString.offset;
- while (n-- != 0) {
- if (v1[i++] != v2[j++])
- returnfalse
;- }
- returntrue;
- }
- }
- returnfalse;
- }
可以看到,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類如下:
- package pojo;
- import java.io.Serializable;
- import java.util.HashSet;
- import java.util.Set;
- publicclass Customer implements Serializable{
- private Integer id;
- private String userName;
- private String password;
- private String realName;
- private String address;
- private String mobile;
- private Set<Order> orders=new HashSet<Order>(0);
- public Set<Order> getOrders() {
- return orders;
- }
- publicvoid setOrders(Set<Order> orders) {
- this.orders = orders;
- }
- public Customer(String userName,String password,String realName,
- String address,String mobile)
- {
- this.userName=userName;
- this.password=password;
- this.realName=realName;
- this.address=address;
- this.mobile=mobile;
- }
- public Customer()
- {
- }
- public Integer getId() {
- return id;
- }
- publicvoid setId(Integer id) {
- this.id = id;
- }
- public String getUserName() {
- return userName;
- }
- publicvoid setUserName(String userName) {
- this.userName = userName;
- }
- public String getPassword() {
- return password;
- }
- publicvoid setPassword(String password) {
- this.password = password;
- }
- public String getRealName() {
- return realName;
- }
- publicvoid setRealName(String realName) {
- this.realName = realName;
- }
- public String getAddress() {
- return address;
- }
- publicvoid setAddress(String address) {
- this.address = address;
- }
- public String getMobile() {
- return mobile;
- }
- publicvoid setMobile(String mobile) {
- this.mobile = mobile;
- }
- //重寫hashCode方法
- @Override
- publicint hashCode()
- {
- finalint prime=