Java工程师面试必问的equals属性知识

个人博客地址:https://griabcrh.github.io/

我们平常判断两个对象是否相等时直接使用.equals()方法,但你有思考过equals比较的是两个对象的值还是引用地址嘛?

这个问题基本上是面试的常客

提问

请判断,两个对象值相同(x.equals(y) == true),但却可有不同的hash code , 该说法是否正确,为什么?

结合提问,请跟着小雷一起敲一遍代码,下次面试遇到这个问题咱再也不怕了。

涉及到equals肯定少不了equals被重写的场景,下面我将分4个场景介绍。

首先,我们创建一个Student对象,name和age属性

public class Student {
  
  private String name;
  private int age;
  
  public Student(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  public String getName() {
    return name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public int getAge() {
    return age;
  }
  
  public void setAge(int age) {
    this.age = age;
  }
  
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Student)) return false;
​
    Student student = (Student) o;
​
    if (getAge() != student.getAge()) return false;
    return getName().equals(student.getName());
  }
  
  @Override
  public int hashCode() {
    int result = getName().hashCode();
    result = 31 * result + getAge();
    return result;
  }
}

基于Junit编写测试方法

@Test
  public void testEquals()
{
    Student x = new Student("cheng", 20);
    Student y = new Student("cheng", 20);
    System.out.println("x.equals(y) is " + x.equals(y));
    System.out.println("x.hashCode = " + x.hashCode());
    System.out.println("y.hashCode = " + y.hashCode());
    System.out.println("x memory address : " + System.identityHashCode(x));
    System.out.println("y memory address : " + System.identityHashCode(y));
  }

1、equals()和hashCode()被重写

如上Student类中equals和hashCode被重写了,运行测试代码结果如下

x.equals(y) is true
x.hashCode = -1361517349
y.hashCode = -1361517349
x memory address : 1623822117
y memory address : 549696331

从结果中可以看到,equals和hashCode被重写, 比较结果为true, hashCode一样,内存地址不一样

2、equals被重写,hashCode没有被重写

在Student类中,将hashCode()方法注释掉,运行测试代码如下:

x.equals(y) is true
x.hashCode = 1823390262
y.hashCode = 145510702
x memory address : 1823390262
y memory address : 145510702

从结果中可以看到,equals被重写,hashCode没有被重写, 比较结果为true, hashCode不一样,内存地址不一样,且x的hashcode和x的内存地址数值一样,y的hashcode和y的内存地址数值一样

3、equals没被重写,hashCode也没被重写

在Student类中,将equals方法和hashCode方法注释掉,运行测试代码结果如下:

x.equals(y) is false
x.hashCode = 908299026
y.hashCode = 857240709
x memory address : 908299026
y memory address : 857240709

从结果中可以看到,equals没被重写,hashCode也没被重写, 比较结果为false,hashCode不一样,内存地址不一样,且x的hashcode和x的内存地址数值一样,y的hashcode和y的内存地址数值一样

4、equals没被重写,hashCode被重写

在Student类中,将equals方法注释掉,运行测试代码结果如下:

x.equals(y) is false
x.hashCode = -1361517349
y.hashCode = -1361517349
x memory address : 1887922615
y memory address : 854077600

从结果中可以看到,equals没被重写,hashCode被重写, 比较结果为false, hashCode一样,内存地址不一样

总结:

提问:
请判断,两个对象值相同(x.equals(y) == true),但却可有不同的hash code , 该说法是否正确,为什么?

答: 该说法正确,当重写了equals方法但没重写hashCode方法,就会出现这样的问题。

注释:建议将equals和hashCode两个方法一起重写
如果你喜欢本文,请长按二维码关注
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java开发高级进阶公众号

苦不堪言

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值