写两个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 的实现
相关推荐
yong99903 分钟前
带挂载的四轴飞行器模型预测控制(MPC) MATLAB实现
开发语言·matlab
报错小能手7 分钟前
ios开发方向——对于实习开发的app(Robopocket)讲解
开发语言·学习·ios·swift
wjs20249 分钟前
Swift 方法
开发语言
小肥米9 分钟前
分块查找ASL公式推导,为什么是两个ASL之和
数据结构·算法
样例过了就是过了11 分钟前
LeetCode热题100 最小栈
数据结构·c++·算法·leetcode
计算机安禾14 分钟前
【数据结构与算法】第18篇:数组的压缩存储:对称矩阵、三角矩阵与稀疏矩阵
c语言·开发语言·数据结构·c++·线性代数·算法·矩阵
今儿敲了吗15 分钟前
51| 八皇后
c++·笔记·学习·算法·深度优先
pedestrian_h16 分钟前
Java单例模式回顾
java·单例模式·设计模式
a8a30217 分钟前
Spring Boot(快速上手)
java·spring boot·后端
华科易迅18 分钟前
MybatisPlus乐观锁
java·开发语言·mybatis