原创

java面试题-两个对象的hashCode()相同,则equals()也一定为true,对吗?

深入理解HashCode与Equals方法:常见误解与规范协定

概述

在Java中,hashCodeequals方法是常用于对象比较和散列表(如HashMap、HashSet等)实现的两个关键方法。理解它们的正确用法对于Java开发者至关重要,本文将深入探讨这两个方法的一些误解和常规协定,并提供详细的代码示例。

误解:hashCode相同就一定equals相等

错误观念: 两个对象的hashCode()相同,那么它们的equals()一定返回true

示例代码:

String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(), str2.hashCode()));
System.out.println(str1.equals(str2));

执行结果:

str1:1179395 | str2:1179395    
false

代码解读: 显然,"通话"和"重地"的hashCode()相同,但equals()却为false。在散列表中,hashCode()相等仅表示两个键值对的哈希值相等,不一定能得出键值对相等。

协定规范

为了避免上述误解,hashCodeequals方法有一些常规协定:

  1. 如果两个对象用equals()比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。

  2. 如果两个对象用equals()比较返回false,并不要求hashCode()方法也一定返回不同的值,但最好返回不同值,以提高哈希表性能。

  3. 重写equals()方法时,必须重写hashCode()方法,以保证equals()方法相等时两个对象hashCode()返回相同的值。

示例与规范实践

示例代码:

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 obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }

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

代码解释:

  • equals()方法重写,比较两个Person对象的nameage属性是否相等。
  • hashCode()方法重写,使用Objects.hash()生成基于nameage的哈希值。

示例应用:

Person person1 = new Person("John", 25);
Person person2 = new Person("John", 25);

System.out.println(person1.equals(person2)); // true
System.out.println(person1.hashCode() == person2.hashCode()); // true

代码解释:

  • 由于equals()返回true,根据规范协定,hashCode()也应该返回相同的值。
正文到此结束
本文目录