重寫equals方法為什么要重寫hashcode方法


1、原因

  Object 的 equals() 默認比較的是對象的內存地址,而 hashCode() 也是對對象的內存地址進行hash。

  因為Hash比equals方法的開銷要小,速度更快,所以在涉及到hashcode的容器中(比如HashSet),判斷自己是否持有該對象時,會先檢查hashCode是否相等,如果hashCode不相等,就會直接認為不相等,並存入容器中,不會再調用equals進行比較。

  這樣就會導致,即使該對象已經存在HashSet中,但是因為hashCode不同,還會再次被存入。因此要重寫hashCode保證:如果equals判斷是相等的,那hashCode值也要相等。

2、測試

  場景:創建一個Product對象,認為商品id相等就是同一個對象。

(1)只重寫equals方法,不重寫hashcode方法

package com.yang.servlet;

import java.util.HashSet;
import java.util.Objects;

public class Product {
    private Integer id;
    private String name;

    public Product(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 重寫equals
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Product product = (Product) o;
        return Objects.equals(id, product.id);
    }

    
    public static void main(String[] args) {
        Product product1 = new Product(1, "包子");
        Product product2 = new Product(1, "饅頭");

        HashSet<Product> products = new HashSet<Product>();
        products.add(product1);
        products.add(product2);
        // 使用equals判斷是否相等
        System.out.println(product1.equals(product2));
        // 查看HashSet中元素個數
        System.out.println(products.size());

    }
}

  測試結果:

true // 可以看到判斷是相等的
2 // 但是還是存到了HashSet中

  雖然id相同,但是還是添加到了hashSet中。

(2)重寫hashcode方法

@Override
public int hashCode() {
    return Objects.hash(id);
}

  測試結果:

true // 可以看到判斷是相等的
1 // 並且第二個值並沒有存到HashSet中

 


免責聲明!

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



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