写两个hascode和equals的例子

目录

[示例1:不重写 hashCode 和 equals](#示例1:不重写 hashCode 和 equals)

[示例2:只重写 equals 方法](#示例2:只重写 equals 方法)

[示例3:正确重写 equals 和 hashCode](#示例3:正确重写 equals 和 hashCode)

示例4:在哈希集合中的行为

关键规则总结:


我将通过几个例子来帮助你理解 hashCodeequals 方法的作用和使用场景。

示例1:不重写 hashCodeequals

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

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Person p1 = new Person("Alice", 25);
        Person p2 = new Person("Alice", 25);

        System.out.println(p1.equals(p2)); // false
        System.out.println(p1.hashCode() == p2.hashCode()); // false
    }
}

解释

  • 默认的 equals 方法比较的是对象的引用(是否为同一个对象)
  • 默认的 hashCode 返回对象的内存地址转换后的整数
  • 即使两个对象内容相同,它们也是不同的对象实例

示例2:只重写 equals 方法

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

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重写equals方法
    @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 && name.equals(person.name);
    }

    public static void main(String[] args) {
        Person p1 = new Person("Alice", 25);
        Person p2 = new Person("Alice", 25);

        System.out.println(p1.equals(p2)); // true
        System.out.println(p1.hashCode() == p2.hashCode()); // false
    }
}

解释

  • 重写后 equals 根据内容判断为 true
  • hashCode 仍基于内存地址,导致哈希值不同
  • 问题 :这违反了 hashCode 的约定(相等的对象必须有相同的哈希值)

示例3:正确重写 equalshashCode

复制代码
import java.util.Objects;

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

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重写equals方法
    @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 && name.equals(person.name);
    }

    // 重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public static void main(String[] args) {
        Person p1 = new Person("Alice", 25);
        Person p2 = new Person("Alice", 25);

        System.out.println(p1.equals(p2)); // true
        System.out.println(p1.hashCode() == p2.hashCode()); // true
    }
}

解释

  • equals 根据内容判断对象是否相等
  • hashCode 根据内容计算哈希值
  • 符合 Java 规范:相等的对象必须有相同的哈希值

示例4:在哈希集合中的行为

复制代码
import java.util.HashSet;
import java.util.Set;

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

    public Person(String name, int age) {
        this.name = name;
        this.age = 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 && name.equals(person.name);
    }

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

    public static void main(String[] args) {
        Set<Person> set = new HashSet<>();
        set.add(new Person("Bob", 30));
        set.add(new Person("Bob", 30));

        System.out.println(set.size()); // 1
    }
}

解释

  • 由于正确重写了 equalshashCode
  • HashSet 能够正确判断两个内容相同的对象为重复元素
  • 如果没有正确重写这两个方法,Set 会包含重复元素

关键规则总结:

  1. equals 的约定
    • 自反性:x.equals(x) 必须为 true
    • 对称性:x.equals(y) 为 true 时,y.equals(x) 也必须为 true
    • 传递性:如果 x.equals(y) 和 y.equals(z) 为 true,则 x.equals(z) 也必须为 true
    • 一致性:多次调用 x.equals(y) 结果不变
    • 任何非 null 对象与 null 比较结果为 false
  1. hashCode 的约定
    • 相等的对象必须具有相同的哈希值
    • 哈希值在对象的生命周期内不应改变
    • 不相等的对象可以有相同的哈希值(哈希冲突)
  1. 最佳实践
    • 当重写 equals 方法时,必须重写 hashCode 方法
    • 使用相同的字段来计算 equalshashCode
    • 可以使用 Objects.hash() 方法简化 hashCode 的实现
相关推荐
Dcs8 分钟前
IDEA 2025.2又整大活!AI 助手脱胎换骨,Spring 调试一秒看透,连 Java 25 和虚拟线程都安排上了!
java
小沈熬夜秃头中୧⍤⃝12 分钟前
Python 基础语法(二):流程控制语句详解
开发语言·数据库·python
MSXmiao25 分钟前
2048小游戏
数据结构·c++·算法
Boilermaker199238 分钟前
【Java EE】Spring AOP
java·java-ee
JosieBook42 分钟前
【web应用】前后端分离项目基本框架组成:Vue + Spring Boot 最佳实践指南
前端·vue.js·spring boot
钮钴禄·爱因斯晨1 小时前
数据结构 | 树的秘密
c语言·开发语言·数据结构
黄晓魚1 小时前
open3d python 鞋底点云点胶路径识别
开发语言·python·open3d
CoovallyAIHub1 小时前
论文精读|YOLO系列最新模型水下实测:v8为何能斩获80.9% mAP?
深度学习·算法·计算机视觉
Code blocks1 小时前
SpringBoot中策略模式使用
java·spring boot·后端·mybatis·策略模式
Ghost-Face1 小时前
《算法导论》笔记--归并排序 & 算法原理
算法