【面試】hashCode與equals兩者之間的關係 / == 和equals / 爲什麼要重寫equals方法 / 重寫equals /hashcode方法 / 爲什麼要重寫hashCode方法


1、hashCode與equals兩者之間的關係

  1. 如果兩個對象相同(即用equals比較返回true),那麼它們的hashCode值一定要相同!!!!
  2. 如果兩個對象不同(即用equals比較返回false),那麼它們的hashCode值可能相同也可能不同。
  3. 如果兩個對象的hashCode相同(存在哈希衝突),那麼它們可能相同也可能不同(即equals比較可能是false也可能是true)
  4. 如果兩個對象的hashCode不同,那麼他們肯定不同(即用equals比較返回false)

2、== 和equals的區別`

== 是運算符,用於比較兩個變量是否相等。
`equals`,是Objec類的方法,用於比較兩個對象是否相等.
默認Object類的equals方法是比較兩個對象的地址,跟==的結果一樣

3、爲什麼要重寫equals()方法?

Object類中equals方法比較的是兩個對象的引用地址
只有對象的引用地址指向同一個地址時,才認爲這兩個地址是相等的,否則這兩個對象就不相等。
如果有兩個對象,他們的屬性是相同的,但是地址不同:
這樣使用equals()比較得出的結果是不相等的,而我們需要的是這兩個對象相等。
因此默認的equals()方法是不符合我們的要求的;
這個時候我們就需要對equals()方法進行重寫以滿足我們的預期結果。
在java的集合框架中需要用到equals()方法進行查找對象,如果集合中存放的是自定義類型,
並且沒有重寫equals()方法,則會調用Object父類中的equals()方法按照地址比較,
往往會出現錯誤的結果,此時我們應該根據業務需求重寫equals()方法。

4、重寫equals()方法

  • 重寫equals方法需要遵循Java如下規則,否則編碼行爲會難以揣測:
自反性:對於任意的對象x,x.equals(x)返回true(自己一定等於自己)
對稱性:對於任意的對象x和y,若x.equals(y)true,則y.equals(x)亦爲true
傳遞性:對於任意的對象x、y和z,若x.equals(y)true且y.equals(z)也爲true,則x.equals(z)亦爲true
一致性:對於任意的對象x和y,x.equals(y)的第一次調用爲true,那麼x.equals(y)的第二次、第三次、第n次調用也均爲true,前提條件是沒有修改x也沒有修改y;
對於非空引用x,x.equals(null)永遠返回爲false
  • 根據以上,上代碼
public class Test {
    public static void main(String[] args) {
        Employee employee = new Employee("zhangsan",1);
        Employee employee2 = new Employee("zhangsan",1);
        Person p1 = new Person("zhangsan");

        System.out.println(p1.equals(employee));
        System.out.println(p1.equals(employee2));
        System.out.println(employee.equals(employee2));

        Employee employee3 = new Employee(null,1);
        Employee employee4 = new Employee(null,1);
        Person p2 = new Person(null);
        System.out.println(p2.equals(employee3));
        System.out.println(p2.equals(employee4));
        System.out.println(employee3.equals(employee4));
    }
}

class Person {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Person(String name) {
        this.name = name;
    }
  @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if(obj == null || getClass() != obj.getClass()){
            return false;
        }
        Person person = (Person) obj;
        if(person.getName() == null | name == null) {
            return false;
        } else {
            return name.equalsIgnoreCase(person.getName());
        }
    }
}
class Employee extends Person {
    private int id;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Employee(String name, int id) {
        super(name);
        this.id = id;
    }
    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if(obj == null || getClass() != obj.getClass()){
            return false;
        }
        Employee employee = (Employee) obj;
        if(employee.getName() == null | getName() == null) {
            return false;
        }else {
            return getName().equalsIgnoreCase(employee.getName()) && employee.getId() == id;
        }
    }
}
12false
3true
456false

5、爲什麼要重寫hashCode()方法?

hashCode()方法用於散列數據的快速存儲,
HashSet/HashMap/Hashtable類存儲數據時都是根據存儲對象的hashcode值來進行分類存儲的,
一般先根據hashcode值在集合中進行分類,在根據equals()方法判斷對象是否相同。
HashMap對象是根據其Key的hashCode來獲取對應的Value。
生成一個好的hashCode值能提高HashSet查找的性能,差的hashCode值不但不能提高性能,
甚至可能造成錯誤。比如hashCode方法中返回常量,
使HashSet的查找效率退化爲List集合的查找效率;
hashCode方法中返回隨機數,會讓查找結果變的不可預測。
一個好的hashCode生成方式是讓對象中的關鍵屬性與質數相乘,並將積相加獲取。

6、什麼時候需要重寫hashCode()方法?

在每個類中,在重寫 equals 方法的時侯,一定要重寫 hashcode 方法
如果不這樣做,你的類違反了hashCode的通用約定,這會阻止它在HashMap和HashSet這樣的集合中正常工作。

7、重寫hashCode()方法:

  • 重寫hashCode()方法需要遵循hashCode()協定:
  • 一致性:在Java應用程序執行期間,在對同一對象多次調用hashCode方法時,必須一致地返回相同的整數,前提是將對象進行hashcode比較時所用的信息沒有被修改。
  • equals:如果根據equals()方法比較,兩個對象是相等的,那麼對這兩個對象中的每個對象調用hashCode()方法都必須生成相同的整數結果,注:這裏說的equals()方法是指Object類中未被子類重寫過的equals()方法。
  • 如果根據equals()方法比較,兩個對象不相等,那麼對這兩個對象中的任一對象上調用hashCode方法不一定生成不同的整數結果。但是,程序員應該意識到,爲不相等的對象生成不同整數結果可以提高哈希表的性能。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章