為什么要同時重寫equals和hashcode方法


廢話不多說,先上案例,如下

先定義一個User類,並定義2個屬性,構造方法,new 2個對象,user1 user2

    public static void main(String[] args) {
        User user1 = new User(1,"張三");
        User user2 = new User(1,"張三");
        System.out.println(user1.hashCode());
        System.out.println(user2.hashCode());
        System.out.println(user1.equals(user2));
        Set<User> set = new HashSet<User>();
        set.add(user1);
        set.add(user2);
        System.out.println(set);
    }

運行程序,輸出結果如下:

 

 

重寫 hashcode 和 equals 重新運行,結果如下:

 

 

2張運行結果可以看出hashcode 值相等,且 equals 返回 true HashSet 起到去重效果

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name.equals(user.name);
    }

    @Override
    public int hashCode() {
        int result = age;
        result = 31 * result + name.hashCode();
        return result;
    }

 

以下是關於hashcode的一些規定:

兩個對象相等,hashcode一定相等,兩個對象不等,hashcode不一定不等;

hashcode相等,兩個對象不一定相等,hashcode不等,兩個對象一定不等;

 

以下是Object源碼中hashcode 和 equals的具體實現

public native int hashCode();

public boolean equals(Object obj) {
        return (this == obj);
    }

不重寫 hashcode 和 equals 的情況,默認使用Object內中的 equals 和hashcode方法

默認情況下Object 為不同對象生成的 hashcode 一般是不同的,默認equals 方法比較的是2個對象的內存地址,所以比較結果為false

 

我們只重新hashcode方法,不重新equals 方法,運行程序結果如下:

雖然hashcode值相同,但是比較的任然是內存地址,然而2個對象的內存地址是不一樣的,所以比較結果任然是false,只有同時重新hashcode 和equals 才能判讀2個對象是否相等,才能達到去重效果;

注意:==比較的是內存地址, equals比較的是值是否相等

 


免責聲明!

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



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