爲什麼重寫equals方法
假設有一個User對象,包括主鍵(id)、姓名(name),年齡(age)三個屬性。現在我們new出兩個User對象,來比較他們是否相等。
這裏我們只需要姓名和年齡相等,就認爲User對象相等。
public class User {
private String id;
private String name;
private String age;
...
}
User user1 = new User("1", "xiaohua", "14");
User user2 = new User("2", "xiaohua", "14");
System.out.println((user1.equals(user2)));//打印爲false
爲什麼結果爲false呢?查看源碼可知,比較的是兩個對象的地址,相當於user1==user2,所以肯定不相等。
public boolean equals(Object obj) {
return (this == obj);
}
接下來我們重寫equals方法,直接上代碼。
@Override
public boolean equals(Object obj) {
/**
* 1.判斷地址是否相等,如果地址相等說明是同一對象
* 如果地址不相等,再執行下面的操作
*/
if (this == obj) {
return true;
}
/**
* 2.判斷非空性
* 對於任意非空引用x,x.equals(null)應該返回false
*/
if (obj == null) {
return false;
}
/**
* 3.比較對象中的字段
* 字段相等,則這兩個對象相等
*/
if (obj instanceof User) {
User other = (User) obj;
if (equalsStr(this.name, other.name)
&& equalsStr(this.age, other.age)) {
return true;
}
}
return false;
}
爲什麼重寫hashCode方法
首先我們先看下默認的hashCode方法
@Override
public int hashCode() {
return super.hashCode();
}
接下來我們再舉一個案例,將new出的兩個User對象放入HashCode中,再進行比較
@Test
public void testHashCodeObj(){
User user1 = new User("1", "xiaohua", "14");
User user2 = new User("2", "xiaohua", "14");
Set<User> userSet = new HashSet<>();
userSet.add(user1);
userSet.add(user2);
System.out.println(user1.equals(user2));//結果:true
System.out.println(user1.hashCode() == user2.hashCode());//結果:false
}
爲什麼結果是false呢?通過看hashSet的add方法能夠得知,add方法裏面使用了對象的hashCode方法來判斷,所以我們需要重寫hashCode方法來達到我們想要的效果。接下來我們重寫HashCode方法。
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (name == null ? 0 : name.hashCode());
result = 31 * result + (age == null ? 0 : age.hashCode());
return result;
}
所以hashCode是用於散列數據的快速存取,如利用HashSet/HashMap/Hashtable類來存儲數據時,都會根據存儲對象的 hashCode值來進行判斷是否相同的。