為什么要重寫equals()方法與hashCode()方法


在java中,所有的對象都是繼承於Object類。Ojbect類中有兩個方法equals、hashCode,這兩個方法都是用來比較兩個對象是否相等的。

在未重寫equals方法我們是繼承了object的equals方法,那里的 equals是比較兩個對象的內存地址,顯然我們new了2個對象內存地址肯定不一樣

  • 對於值對象,==比較的是兩個對象的值
  • 對於引用對象,比較的是兩個對象的地址

Object 默認的equals方法同==,一般來說我們的對象都是引用對象,要重寫equals方法。

1     public boolean equals(Object obj) {
2         return (this == obj);
3     }
1     public static void main(String[] args) {
2         Object c=new Object();
3         Object d=new Object();
4         System.out.println(c.equals(d));//false
5 
6     }

這個比較下,結果是false,也就是這兩個對象不一樣,但是有些業務,我們需要證明一個類的下面的實例對象時相等的,這時候我們就必須重寫equlas方法了。

 

如下代碼,我們新建一個對象Student,並重寫equals與hashCode方法

 1 public class Student {
 2 
 3     private int no;
 4 
 5     private String name;
 6 
 7 
 8     @Override
 9     public boolean equals(Object o) {
10         if (this == o) return true;
11         if (o == null || getClass() != o.getClass()) return false;
12 
13         Student student = (Student) o;
14 
15         if (no != student.no) return false;
16         return !(name != null ? !name.equals(student.name) : student.name != null);
17 
18     }
19 
20     @Override
21     public int hashCode() {
22         int result = no;
23         result = 31 * result + (name != null ? name.hashCode() : 0);
24         return result;
25     }
26 
27     public int getNo() {
28         return no;
29     }
30 
31     public void setNo(int no) {
32         this.no = no;
33     }
34 
35     public String getName() {
36         return name;
37     }
38 
39     public void setName(String name) {
40         this.name = name;
41     }
42 }
1         Student a=new Student();
2         Student b=new Student();
3         System.out.println(a.equals(b));//ture    

 

此時可以看出a、b對象相等.

 

hashCode方法也是可以用來比較兩個對象是否相等的。但是我們很少使用,應該說是很少直接使用。hashCode方法返回的是一個int值,可以看做是一個對象的唯一編碼,如果兩個對象的hashCode值相同,我們應該認為這兩個對象是同一個對象。

 

一般如果使用java中的Map對象進行存儲時,他會自動調用hashCode方法來比較兩個對象是否相等。

所以如果我們對equals方法進行了重寫,建議一定要對hashCode方法重寫,以保證相同的對象返回相同的hash值,不同的對象返回不同的hash值。

 

1、重寫equals方法時需要重寫hashCode方法,主要是針對Map、Set等集合類型的使用;

a: Map、Set等集合類型存放的對象必須是唯一的;

b: 集合類判斷兩個對象是否相等,是先判斷equals是否相等,如果equals返回TRUE,還要再判斷HashCode返回值是否ture,只有兩者都返回ture,才認為該兩個對象是相等的。

2、由於Object的hashCode返回的是對象的hash值,所以即使equals返回TRUE,集合也可能判定兩個對象不等,所以必須重寫hashCode方法,以保證當equals返回TRUE時,hashCode也返回Ture,這樣才能使得集合中存放的對象唯一。

 

 

 

個人感覺equals重寫,是站在使用的角度上考慮的:類設計者不希望通過內存地址來比較兩個對象是否相等,重寫這個equals方法,能夠方便的使用Collection<E>操作自定義對象E(Collection中很多方法涉及E.equals()的);而hashCode的重新,是方便Map<K,V>的使用,良好的自定義hashCode,會極大的提高Map的使用效率。

為啥說equals重新時,一定要重寫hashCode?感覺這么理解不知行不行:既然自定義類重寫了equals方法,說明類設計者不希望通過內存地址來比較兩個對象是否相等了。而Object的hashCode也是對象的內存地址,既然不希望通過地址比較對象,那么以內存地址作為hashCode也就沒有實際使用意義了,索性將自定義對象的hashCode方法也重寫了吧!

 

參考: hashCode的作用   重寫equals方法為什么要重寫hashCode方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM