自学内容网 自学内容网

Java基础面试题06:hashCode()和equals()方法的重要性体现在什么地方?

前言

Java中的hashCode()equals()方法看似是干同一件事,但它们的使用场景和作用却大有不同。为了让程序更高效、更准确地运行,我们需要对这两者有深入的了解,并掌握它们的重写规则。

hashCode()和equals()的基础知识

什么是hashCode?

hashCode()是用来返回一个哈希值(int类型)的,它的作用是确定对象在散列表(如HashMapHashSet)中的存储位置。

public class Demo {
    public static void main(String[] args) {
        String str = "aa";
        System.out.println(str.hashCode());  // 输出结果为3104
    }
}
  • 哈希值的作用
    可以把哈希值看成是对象的身份证号,散列表会根据这个“身份证号”快速定位到对象的位置。
  • 定义在哪
    hashCode()方法定义在java.lang.Object类中,这意味着所有类都默认拥有这个方法。

什么是equals?

equals()方法用于比较两个对象是否“相等”。
默认情况下,它和==一样,比较的是对象的内存地址。但是,开发中我们经常需要比较对象的内容,比如两个学生对象的名字是否相等,这时就需要重写equals()方法。


hashCode()和equals()的关系

两条重要结论

  1. 如果两个对象通过equals()方法比较相等,它们的hashCode()值必须相等
    (也就是说:equals()是绝对可靠的。)
  2. 如果两个对象的hashCode()值相等,它们通过equals()方法比较时不一定相等
    (这意味着:hashCode()是相对可靠的。)

这两个结论很重要,后面会用它们来解释为什么要同时重写hashCode()equals()


为什么要重写equals()?

默认情况下,equals()方法比较的是两个对象的内存地址。如果两个对象的地址不同,即使它们的内容完全一样,equals()也会返回false

举个例子:

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }
}

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

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

如何重写equals()?

如果我们希望两个name相同的Person对象被认为是相等的,就需要重写equals()方法:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true; // 自反性
    if (obj == null || getClass() != obj.getClass()) return false;
    Person person = (Person) obj;
    return Objects.equals(name, person.name);
}

重写equals()需要遵守的规则

  • 自反性x.equals(x)必须返回true
  • 对称性:如果x.equals(y)true,那么y.equals(x)也必须为true
  • 传递性:如果x.equals(y)true,并且y.equals(z)true,那么x.equals(z)也必须为true
  • 一致性:如果两个对象没有变化,多次调用x.equals(y),结果必须一致。
  • 非空性x.equals(null)必须返回false

为什么要重写hashCode()?

当我们重写了equals(),还必须重写hashCode()
这是因为,如果两个对象被认为是相等的(通过equals()),它们必须有相同的哈希值,否则会影响集合类(如HashSetHashMap)的正常工作。

举个例子:
假设我们有两个内容相同的Person对象:

Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
  • 如果只重写了equals()
    • HashSet可能会认为它们是两个不同的对象,导致HashSet中存储了重复数据。
  • 如果同时重写了hashCode()
    • HashSet会根据相同的哈希值,将它们识别为同一个对象,避免重复存储。

重写hashCode()的方法

在重写hashCode()时,应该确保相等的对象有相同的哈希值。通常,可以通过Objects.hash()方法快速生成哈希值。

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

总结:hashCode()和equals()的搭配使用

简单记住:

  1. 如果重写了equals(),一定要重写hashCode()
  2. equals()保证逻辑上的相等,hashCode()保证性能上的高效。

两者的重要性体现在:

  • 在集合类中(如HashSetHashMap),hashCode()用于快速定位,equals()用于最终确认是否相等。
  • 通过正确重写这两个方法,可以避免重复数据、保证集合操作的准确性。

参考代码示例:综合重写equals()和hashCode()

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }

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

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

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

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

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

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

通过这个示例,可以看到两个name相同的Person对象在HashSet中只存储一次。


掌握了这些,你就能够在面试中清晰地解释hashCode()equals()的作用及它们之间的关系啦!

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。
这是大佬写的
7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!


原文地址:https://blog.csdn.net/liuguojiang1128/article/details/144122187

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!