hashCode()與equals()

在hash表操作中,hashCode()和equals()方法用於判斷兩個對象是否相等,在HashSet的contains()方法add()方法、HashMap的contains()方法和put()方法等集合框架中廣泛使用。
hashCode()和equals()方法在Object類中被定義,java中任何類都具有這兩個方法。在新定義類時,若涉及到新定義類對象的比較,則需要重寫這兩個方法。

如下命題成立
命題1:兩個對象equals()方法返回true時,hashCode()方法返回值一定相同;
重寫equals(Object obj)方法時,有必要重寫hashcode()方法,確保通過equals(Object obj)方法判斷結果爲true的兩個對象具備相等的hashcode()返回值。

命題1的逆否:兩個對象的hashCode()返回值不同,則equals()方法返回值一定false;

命題2:兩個對象equals()返回值false時,hashCode()方法值可以相等;

命題3:兩個對象hashCode()相等時,equals()可能爲true或false;

所以,在判斷兩個對象是否相等時,先判斷hashCode(),hashCode()不等時直接返回false;hashCode()相等時再判斷equals()方法。

示例代碼
由於Object類的hashCode()是將對象的內部地址轉換成整數來返回,所以當某個類沒有覆蓋hashCode()方法時,equals()方法將失敗。
import java.util.*;

public class Main1 {
    static class Name {
        String f = null;
        String l = null;

        public Name(String f, String l) {
            this.f = f;
            this.l = l;
        }
        // 沒有重寫hashCode()
        @Override
        public boolean equals(Object obj) {
            Name o = (Name)obj;
            return this.f.equals(o.f) && this.l.equals(o.l);
        }
    }

    public static void main(String[] args) {
        HashSet<Name> set = new HashSet<>();

        Name n1 = new Name("pan", "shan");
        set.add(n1);

        Name n2 = new Name("pan", "shan");
        boolean res = set.contains(n2);

        System.out.println(res);// false
    }
}

同時覆蓋equals()和hashCode()方法

import java.util.*;

public class Main1 {
    static class Name {
        String f = null;
        String l = null;

        public Name(String f, String l) {
            this.f = f;
            this.l = l;
        }

        // 同時重寫equals()和hashCode()
        @Override
        public boolean equals(Object obj) {
            Name o = (Name)obj;
            return this.f.equals(o.f) && this.l.equals(o.l);
        }
        @Override
        public int hashCode() {
            return this.f.hashCode()*31 + this.l.hashCode();
        }
    }

    public static void main(String[] args) {
        HashSet<Name> set = new HashSet<>();

        Name n1 = new Name("pan", "shan");
        set.add(n1);

        Name n2 = new Name("pan", "shan");
        boolean res = set.contains(n2);

        System.out.println(res);// true
    }
}
發佈了82 篇原創文章 · 獲贊 22 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章