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