1. 程式人生 > >重寫equals和hashCode方法原因

重寫equals和hashCode方法原因

註釋 ons tag with spa detail 代碼 auth tail

轉載自:https://blog.csdn.net/zh_w_h163/article/details/11907869

在程序中,我們習慣使用equals方法來比較兩個對象,繼承自Object的equals方法默認的比較兩個對象的內存地址(String類重寫了equals方法,比較字符串的內容)。假如我們創建了兩個Person對象,二者同名同姓,我們認為二者相同,但若是用equals方法比較二者,由於內存地址不同,返回的仍是false。因此我們需要重寫equlas方法,以我們的視角來建立規則。我們以實例來分析:
我們創建一個類並重寫其equals方法,並創建兩個對象person1和person2對象,然後比較二者。

1.只重寫equals方法:代碼

 1 /**
 2  * 
 3  */
 4 package kklazy.test.equalsAndHashCode;
 5 
 6 /**
 7  * @author whh
 8  *
 9  */
10 public class Person {
11     
12     private String name;
13     private int age;
14     
15     /**
16      * @return the name
17      */
18     public String getName() {
19         return
name; 20 } 21 /** 22 * @param name the name to set 23 */ 24 public void setName(String name) { 25 this.name = name; 26 } 27 /** 28 * @return the age 29 */ 30 public int getAge() { 31 return age; 32 } 33 /** 34 * @param age the age to set
35 */ 36 public void setAge(int age) { 37 this.age = age; 38 } 39 /* (non-Javadoc) 40 * @see java.lang.Object#hashCode() 41 */ 42 // @Override 43 // public int hashCode() { 44 // final int prime = 31;//只要為素數就可以 45 // int result = 1; 46 // result = prime * result + age; 47 // result = prime * result + ((name == null) ? 0 : name.hashCode()); 48 // return result; 49 // } 50 /* (non-Javadoc) 51 * @see java.lang.Object#equals(java.lang.Object) 52 */ 53 @Override 54 public boolean equals(Object obj) { 55 if (this == obj)// 如果二者引用的為同一個對象,則返回true 56 return true; 57 if (obj == null)// 如果比較的對象為null,返回false 58 return false; 59 if (getClass() != obj.getClass()) 60 return false; 61 Person other = (Person) obj; 62 if (age != other.age) 63 return false; 64 if (name == null) { 65 if (other.name != null) 66 return false; 67 } else if (!name.equals(other.name)) 68 return false; 69 return true; 70 } 71 72 73 74 }

通過Junit測試,並將兩個對象存放到HashSet之中,代碼如下:

 1 /**
 2  * 
 3  */
 4 package kklazy.test;
 5 
 6 import java.util.HashSet;
 7 import java.util.Set;
 8 
 9 import org.junit.Test;
10 import org.junit.runner.RunWith;
11 import org.springframework.test.context.ContextConfiguration;
12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
13 
14 import kklazy.test.equalsAndHashCode.Person;
15 
16 /**
17  * @author whh
18  *
19  */
20 @RunWith(SpringJUnit4ClassRunner.class)
21 @ContextConfiguration(locations = { "classpath*:/beans/**/*.xml" })
22 public class EqualsAndHashCodeJunitTest {
23     Set<Person> set = new HashSet<Person>();
24     @Test
25     public void test(){
26         Person person1=new Person();        
27         person1.setName("wang");        
28         person1.setAge(18);        
29         Person person2=new Person();        
30         person2.setName("wang");        
31         person2.setAge(18);        
32         System.out.println("返回結果:"+person1.equals(person2));        
33         set.add(person1);        
34         set.add(person2);        
35         System.out.println("set存在"+set.size()+"個對象\n"+set);
36     }
37 
38 }

結果如下所示:二者比較結果:trueset存在2個對象:[com.zhang.demo.Person@1ceebfa, com.zhang.demo.Person@1e6743e]
此時我們發現一個問題,雖然通過重寫equals方法判斷兩個對象相等,但二者都存入到了set之中。納尼?眾所周知,set中只能存入不同的對象,顯然對於HashSet來說,僅僅重寫equals方法是不夠的(對於HashMap也一樣),通過了解集合比較對象的原理,我們才知道,原來集合先比較兩個對象的HashCode是否相等,若相等,則通過equlas方法比較,若兩個方法都通過,則兩個對象被視為同一個對象。接下來,我們再將hashCode方法重寫。
2.重寫hashCode方法:把註釋的hashCode方法代碼放開

然後在通過以上的測試方法測試,結果如下:

二者比較結果:true
set存在1個對象:[com.zhang.demo.Person@d6168d67] 此時,HashSet之中只存入了一個對象。

重寫equals和hashCode方法原因