重写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 @   jingyi_up  阅读(1562)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示