面试tips--java--equals() & hashCode()

1. equals() 方法

  • 作用 :用于比较两个对象的 内容是否相等。

  • 默认实现 :在 Object 类中,equals() 默认使用 == ,比较的是对象的 内存地址(即是否为同一个对象)。

  • 常见重写场景 :当我们希望比较对象的"内容"而不是"地址"时,就需要重写 equals() 方法。

    • 比如 String 类就重写了 equals(),所以 new String("abc").equals(new String("abc")) 会返回 true,即使它们不是同一个对象。

例子:

java 复制代码
public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 内存地址相同,直接true
        if (o == null || getClass() != o.getClass()) return false; // 类型不同直接false
        Person person = (Person) o;
        return age == person.age && name.equals(person.name); // 内容比较
    }
}

2. hashCode() 方法

  • 作用 :返回对象的 哈希值 (int 类型),主要用于 哈希结构的集合 (如 HashMap、HashSet、Hashtable 等)。

  • 哈希表存储原理:

    1. 插入对象时,先计算对象的 hashCode()。

    2. 用 hashCode() 定位到某个"桶"(bucket)。

    3. 如果桶中有多个对象,再用 equals() 判断对象是否相同。

  • 默认实现 :在 Object 类中,hashCode() 会根据对象的内存地址计算,因此不同对象一般哈希值不同。

例子:

java 复制代码
public class Person {
    private String name;
    private int age;

    @Override
    public int hashCode() {
        return name.hashCode() + age;
    }
}

3. 为什么重写 equals() 必须重写 hashCode()?

3.1 Java 规定

Java 规定了 equals() 与 hashCode() 的 契约:

  1. 如果两个对象 equals() 返回 true,那么它们的 hashCode() 必须相等。

  2. 如果两个对象 equals() 返回 false,它们的 hashCode() 可以相等(但最好减少冲突)。

3.2 原因

如果只重写了 equals(),没重写 hashCode(),可能导致集合中找不到对象。

示例:

java 复制代码
Person p1 = new Person("Tom", 18);
Person p2 = new Person("Tom", 18);

HashSet<Person> set = new HashSet<>();
set.add(p1);

System.out.println(set.contains(p2));
  • 如果 只重写了 equals():

    • p1.equals(p2) 为 true(内容相等)。

    • 但 p1.hashCode() 和 p2.hashCode() 不同(因为默认按内存地址算)。

    • HashSet 会认为它们在不同的桶中 → contains(p2) 返回 false ❌。

  • 如果 同时重写了 equals() 和 hashCode():

    • 哈希值相同,定位到同一个桶。

    • 再用 equals() 比较内容 → 找到对象 → contains(p2) 返回 true ✅。


4. 正确的重写方式

推荐使用 IDE 自动生成 ,例如 IntelliJ IDEA/ Eclipse 可以自动生成基于字段的 equals() 和 hashCode()。

示例(推荐写法):

java 复制代码
import java.util.Objects;

public class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

5. 总结

  1. equals():比较对象的内容是否相等。

  2. hashCode():返回对象的哈希值,用于哈希集合快速查找。

  3. 必须遵守契约:

    • equals() 相等 → hashCode() 必须相等。

    • 否则哈希集合(HashMap/HashSet)会出现"存了却找不到"的问题。

  4. 正确姿势 :重写 equals() 时,一定要重写 hashCode()。

相关推荐
哦虎!5 小时前
【JavaEE】网络初识
java
for_ever_love__6 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
程序猿追6 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播6 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
欣栀♡6 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室7 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项7 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
墨云安全7 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php