本文正在参加「Java主题月 – Java 刷题打卡」,详情查看 活动链接
一、题目:为什么重写了equals()方法还需要重写hashCode()方法?
为什么我们在比较对象时,重写实体类中的equals时要重写hashCode方法,这次来一探究竟
equals()只是判断对象属性是否相同,hashCode()要判断二者地址是否相同。java中如果要判断两个对象是否相等,需要同时满足地址 + 属性都相同!
如果两个对象相同(即:用 equals() 比较返回true),那么它们的 hashCode 值一定要相同;
如果两个对象的 hashCode 相同,它们并不一定相同;
复制代码
二、代码演示
只重写 equals() 方法,不重写 hashcode() 方法
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
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;
}
}
复制代码
重写equals测试
Student stu1 = new Student("javazhang",26);
Student stu2 = new Student("javazhang",26);
System.out.println("两位同学是一个人吗?"+stu1.equals(stu2));
System.out.println("stu1.hashCode() = "+stu1.hashCode());
System.out.println("stu1.hashCode() = "+stu2.hashCode());
复制代码
重写equals测试
两位同学是一个人吗?true
stu1.hashCode() = 1013423070
stu1.hashCode() = 380936215
复制代码
重写 equals() 时,也重写了 hashCode() 方法
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
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;
}
}
复制代码
一起重写的输出
两位同学是一个人吗?true
stu1.hashCode() = -818588175
stu1.hashCode() = -818588175
复制代码
三、思考分析
重写了 equals() 不重写 hashcode() 方法
可能就会出现两个没有关系的对象 equals 相同,equals比较对象属性,但 hashcode 是不相同的。因为此时 Student 类的 hashcode() 方法就是 Object 默认的 hashcode()方 法,由于默认的 hashcode()方法是根据对象的内存地址经哈希算法得来的,两者在内存中的位置不同,new方法开辟新的内存空间,所以 stu1 != stu2,故两者的 hashcode 值不一定相等
根据 hashcode 的规则,两个对象相等其 hash 值一定要相等,不重写hashCode就会自相矛盾。用 hashcode 算法,所以即使字段属性相等,但是产生两个不同的 hashCode 值不等,显然不是我们理解的相等
重写了 equals() 也重写 hashcode() 方法
从 Student 类重写后的 hashcode() 方法中可以看出,重写后返回的新的 hash 值与 Student 的两个属性是有关,这样就确保了对象和对象地址之间的关联性,所以产生的hashCode相等,相对想也相同
四、总结
equals()只是判断对象属性是否相同
hashCode()要判断二者地址是否相同
java中如果要判断两个对象是否相同,需要同时满足地址 + 属性都相同!
如果两个对象相同(即:用 equals() 比较返回true),那么它们的 hashCode 值一定要相同;
如果两个对象的 hashCode 相同,它们并不一定相同;
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END