天天看點

==與equals及equals與hashCode

1、 ==與equals

==: 作用是比較兩個對象位址是否相等。對于基本資料類型比較的是值,引用類型比較的是記憶體位址。

equals:作用也是比較兩個對象是否相等。但是在實際使用中,分兩種情況:

  1. 沒有重寫Object類的equals()方法。如果使用的類沒有重寫equals方法,則等價于使用“==”比較兩個對象,即使用對象位址比較是否相等;
  2. 重寫了Object類的equals()方法。一般,我們會重寫equals()方法,比較兩個對象的内容(可以選擇對象的某些屬性比較)是否相等,如果相等,則傳回true(集兩個對象相等)。
public class Student {
    /**學号*/
    private int sno;
    /**名稱*/
    private String name;

    Student(Integer sno, String name){
        this.sno = sno;
        this.name = name;
    }

    /**
     * 重寫equals方法,隻比較sno
     * @param object
     * @return
     */
    @Override
    public boolean equals(Object object){
        if(object == null){
            return false;
        }
        // 如果是同一個對象則傳回true
        if(this == object){
            return true;
        }
        // 類型不同傳回false
        if(this.getClass() != object.getClass()){
            return false;
        }
        Student stu = (Student)object;
        // 比較學号
        return this.sno == stu.sno;
    }

    public static void main(String[] args) {
        Student stu1 = new Student(202007001,"蘇蘇的唐");
        Student stu2 = new Student(202007002,"同桌甲");
        Student stu3 = new Student(202007001,"蘇蘇");

        System.out.println("stu1與stu2比較:"+stu1.equals(stu2));
        System.out.println("stu1與stu3比較:"+stu1.equals(stu3));

    }
}
           

輸出結果:

stu1與stu2比較:false
stu1與stu3比較:true
           

可以看出,我們重寫equals()方法之後,在比較對象時,就會根據指定對象的屬性比較,如果相等則認為兩個對象相等。

2、equals與hashCode

這篇文章講得很詳細Java hashCode() 和 equals()的若幹問題解答

以下是引用這篇文章的内容:

我們在重寫equals()方法時,需要根據情況判斷是否需要重寫hashCode()方法:

  1. 不會建立“類對應的散清單”時不用重寫hashCode()方法。“不會建立類對應的散清單”是說:我們不會在HashSet, Hashtable, HashMap等等這些本質是散清單的資料結構中,用到該類。例如,不會建立該類的HashSet集合。像我們的Student類,如果隻是單純比較兩個Student類,不會把Student類放在HashSet集合,那麼我們就可以不重寫hashCode()方法。
  2. 會建立“類對應的散清單”時需要重寫hashCode()方法。即建立的類會用到本質上是散清單的資料結構中,如HashSet, Hashtable, HashMap。

    在這種情況下,該類的“hashCode() 和 equals() ”是有關系的:

    1)、如果兩個對象相等,那麼它們的hashCode()值一定相同。

    這裡的相等是指,通過equals()比較兩個對象時傳回true。

    2)、如果兩個對象hashCode()相等,它們并不一定相等。

    因為在散清單中,hashCode()相等,即兩個鍵值對的哈希值相等。然而哈希值相等,并不一定能得出鍵值對相等。補充說一句:“兩個不同的鍵值對,哈希值相等”,這就是哈希沖突。

    此外,在這種情況下。若要判斷兩個對象是否相等,除了要覆寫equals()之外,也要覆寫hashCode()函數。否則,equals()無效。

    這時候,要比較Student類,除了重寫equals()方法外,還需要重寫hashCode()方法,如下面的重寫方法。

@Override
    public int hashCode(){
        int nameHashCode = name.hashCode();
        return nameHashCode ^ sno;
    }