两个对象值相同(x.equals(y) == true),但却可有不同的hashcode,该说法是否正确?

原文:https://mp.weixin.qq.com/s/yecWZOXESg9cuaC3z9DebA

我们平常判断两个对象是否相等时直接使用.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方法,就会出现这样的问题。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容