整理好了!2024年最常见 100 道 Java基础面试题(四十一)

上一篇地址:整理好了!2024年最常见 100 道 Java基础面试题(四十)-CSDN博客

八十一、equals 和 hashCode 的区别和联系?

在Java中,equals() 方法和 hashCode() 方法是对象比较和散列表(如 HashMapHashSet)存储中的关键组成部分。它们之间有紧密的联系,但也存在一些重要的区别。

equals() 方法

  1. 目的equals() 方法用于比较两个对象是否相等。它的默认实现检查对象引用的相等性,即比较是否为同一个对象。
  2. 重写:在实际应用中,通常需要重写 equals() 方法来提供逻辑上的等价性判断,比如比较对象的属性值。
  3. 使用场景:常用于对象的比较,如在 HashMap 中查找特定的键值对。

hashCode() 方法

  1. 目的hashCode() 方法返回对象的散列码(一个整数)。在散列表中,散列码用于确定对象存储的索引位置。
  2. 重写:当重写 equals() 方法时,也应该重写 hashCode() 方法,以保持两者之间的一致性。
  3. 使用场景:主要用于散列表的索引操作,如在 HashMap 中根据键快速定位到值。

区别

  1. 功能equals() 是用于比较对象的等价性,而 hashCode() 是用于生成对象的散列码。
  2. 返回类型equals() 返回布尔值(boolean),而 hashCode() 返回一个整数(int)。
  3. 调用equals() 是在对象间进行比较时显式调用的,hashCode() 通常在对象作为散列键时由系统隐式调用。

联系

  1. 一致性:如果两个对象通过 equals() 方法比较是相等的,那么它们的 hashCode() 方法必须返回相同的散列码。
  2. 散列表性能:在散列表中,equals() 和 hashCode() 配合使用可以提高查找、插入和删除操作的性能。

重要原则

根据Java的官方文档,重写 equals() 方法时必须遵守以下原则:

  • 自反性:对于任何非空引用 xx.equals(x) 应该返回 true
  • 对称性:对于任何非空引用 x 和 yx.equals(y) 应该与 y.equals(x) 返回相同的结果。
  • 传递性:对于任何非空引用 xy 和 z,如果 x.equals(y) 返回 truey.equals(z) 返回 true,那么 x.equals(z) 也应该返回 true
  • 一致性:对于任何非空引用 x 和 y,只要在比较过程中它们代表的信息没有被修改,多次调用 x.equals(y) 应该持续返回相同的结果。
  • 非空性:对于任何非空引用 xx.equals(null) 应该返回 false

同时,重写 hashCode() 方法时必须遵守:

  • 一致性:在Java应用程序执行期间,只要对象的equals比较所用的信息没有被修改,那么该对象的hashCode值就应该保持不变。
  • 等效性:如果两个对象通过equals方法比较是相等的,那么这两个对象调用hashCode方法必须产生相同的整数结果。
  • 效率:尽管不严格要求,但建议覆盖hashCode方法的算法能够均匀地分布对象的hashCode值。

示例

public class Person {
    private String name;
    private int 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 && Objects.equals(name, person.name);
    }

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

在这个示例中,Person 类重写了 equals() 方法和 hashCode() 方法,以确保两个 Person 对象在逻辑上相等时,它们的散列码也相同。

总结

equals()hashCode() 是Java中用于对象比较和散列表操作的两个基础方法。它们之间有紧密的联系,尤其是在散列表的使用中。正确实现这两个方法对于确保对象的比较逻辑和散列表的性能至关重要。

八十二、两个对象 equals 相等, hashCode 也相等么?

在Java中,如果两个对象通过 equals() 方法比较结果为相等,那么它们的 hashCode() 方法必须返回相同的散列码。这是 Object 类中 hashCode() 方法的约定,也是实现一个良好的散列表行为的基础。

equals() 方法和 hashCode() 方法的约定

根据Java的官方文档,当你重写 equals() 方法时,必须遵守以下与 hashCode() 方法相关的约定:

  • 等效性:如果两个对象通过 equals() 方法比较是相等的(即 x.equals(y) 返回 true),那么这两个对象调用 hashCode() 方法必须产生相同的整数结果。

这个约定确保了在散列表(如 HashMapHashSet)中,相等的对象能够被映射到同一个散列桶(或称为槽位)。

示例

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 && Objects.equals(name, person.name);
    }

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

在这个示例中,Person 类重写了 equals() 方法和 hashCode() 方法。如果两个 Person 对象具有相同的 nameage,它们通过 equals() 方法比较将返回 true,并且它们的 hashCode() 方法将返回相同的散列码。

注意事项

  • 如果不遵守这个约定,那么使用相等的对象作为键的散列表(如 HashMap 的键)将无法正常工作,因为相等的对象可能会被映射到不同的散列桶,导致无法通过键查找到对应的值。
  • 即使两个对象的 equals() 方法返回 false,它们的 hashCode() 方法也可能返回相同的散列码,但这并不是一个好的实践,因为它会降低散列表的性能。

总结

两个对象如果通过 equals() 方法比较结果为相等,它们的 hashCode() 方法也应该返回相同的散列码。这是Java中对象相等性和散列码一致性的基本约定,对于维护散列表的完整性和性能至关重要。正确实现这两个方法对于确保对象在集合中的预期行为非常关键。

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值