重写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中

 

posted @ 2021-12-16 10:03  jingyi_up  阅读(1558)  评论(0编辑  收藏  举报