重寫equals方法和hashCode方法

爲什麼重寫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值來進行判斷是否相同的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章