You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中hashCode与equals原理疑惑:同参对象为何不相等?

为什么String和自定义Person类的equals/hashCode表现不同?

嘿,这个问题刚好戳中了Java中equals()和hashCode()方法的核心逻辑,我来给你一步步理清楚~

先看String类的表现:为什么内容相同就会equals为true、hashCode一致?

Java的String类主动重写了Object类的equals()和hashCode()方法:

  • equals()方法:不再比较对象的引用地址,而是逐字符对比两个字符串的内容,只要内容完全一致就返回true;
  • hashCode()方法:是根据字符串的字符序列(比如"foo"的每个字符的ASCII值)通过固定算法计算出来的,所以内容相同的String,不管是不是用new创建的不同实例,哈希值必然相同。

这就是为什么你用new String("foo")创建的s1和s2,会得到相同的hashCode和true的equals结果。

再看你的Person类:为什么同参数实例却equals为false、hashCode不同?

你的自定义Person类没有重写equals()和hashCode(),这时候会直接使用父类Object的默认实现:

  • Object.equals():默认比较的是对象的内存引用地址,也就是判断两个对象是不是同一个实例。你用new Person(...)创建了p1和p2两个独立的对象,它们在内存中的地址不一样,所以返回false;
  • Object.hashCode():默认返回的是和对象内存地址相关的数值(不同JVM实现细节有差异,但核心是区分不同实例),所以两个不同的Person实例,哈希值自然不同。

怎么让Person类实现和String一样的行为?

只需要重写equals()和hashCode()方法,并且遵循Java的规范:如果两个对象equals()返回true,它们的hashCode()必须相等;如果hashCode()不等,equals()必须返回false。

修改后的Person类代码如下:

import java.util.Objects;

public class YourClassName {
    public static class Person {
        public String name;
        public String lastName;

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

        @Override
        public boolean equals(Object o) {
            // 引用相同直接返回true
            if (this == o) return true;
            // 传入对象为null或者类型不同,返回false
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            // 比较name和lastName的内容(用Objects.equals避免空指针)
            return Objects.equals(name, person.name) && Objects.equals(lastName, person.lastName);
        }

        @Override
        public int hashCode() {
            // 根据name和lastName计算哈希值
            return Objects.hash(name, lastName);
        }
    }

    public static void main(String[] args) {
        String s1 = new String("foo");
        String s2 = new String("foo");
        System.out.println("String1 hashcode: " + s1.hashCode());
        System.out.println("String2 hashcode: " + s2.hashCode());
        System.out.println("Is String1 equal to String2?: " + s1.equals(s2));

        Person p1 = new Person("John", "Doe");
        Person p2 = new Person("John", "Doe");
        System.out.println("Person1 hashcode: " + p1.hashCode());
        System.out.println("Person2 hashcode: " + p2.hashCode());
        System.out.println("Is Person1 equal to Person2?: " + p1.equals(p2));
    }
}

修改后再运行,你会得到和String一样的结果:p1和p2的hashCode相同,equals()返回true。

额外提醒

如果以后你要把自定义类的对象放进哈希集合(比如HashMap、HashSet),必须重写equals()和hashCode(),否则集合会把内容相同的对象当成不同元素,导致数据重复或者查找失效。

内容的提问来源于stack exchange,提问作者s-kaczmarek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:07:51