为什么重写equals方法同时需要重写hashCode方法?
为什么重写equals方法同时需要重写hashCode方法?
众所周知equals()和hashCode()是Object类中定义的方法。Object类定义的方法如下:
Object的equals()定义如下:
注释部分大概意思是:
请注意,每当重写此方法时,通常需要重写哈希代码,其中规定相等的对象必须具有相等的哈希代码。
Object的hashCode()定义如下:
以上是Object类的定义,我们通过一段代码来解释“为什么重写equals方法同时需要重写hashCode方法?”。
首先我们定义一个实体类RewriteEqHashCode,重写equals()和hashCode()方法:
package com.others.rewritehasheq;
import java.io.Serializable;
import java.util.Objects;
public class RewriteEqHashCode implements Serializable {
private static final long serialVersionUID = -1639762516649859102L;
private Integer id;
private String name;
public RewriteEqHashCode(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RewriteEqHashCode(Integer id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RewriteEqHashCode that = (RewriteEqHashCode) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
然后我们定义一个测试类ValidateEqHashCode:
package com.others.rewritehasheq;
import java.util.HashSet;
/**
* 为什么重写equals方法同时需要重写hashCode方法
*
* @author 小辉GE/小辉哥
* <p>
* 2019年8月29日 下午23:00:00
*/
public class ValidateEqHashCode {
public static void main(String[] args) {
HashSet<Object> hashSet = new HashSet<Object>();
hashSet.add(new RewriteEqHashCode(1001, "张三"));
hashSet.add(new RewriteEqHashCode(1002, "李四"));
hashSet.add(new RewriteEqHashCode(1003, "王五"));
hashSet.add(new RewriteEqHashCode(1001, "张三"));
//遍历
hashSet.forEach((o) -> {
System.out.println(((RewriteEqHashCode) o).getId() + ((RewriteEqHashCode) o).getName());
});
}
}
我们同时注释RewriteEqHashCode类中equals()和hashCode()方法,测试输出结果如下:
我们只注释RewriteEqHashCode类中hashCode()方法,测试输出结果如下:
我们取消注释RewriteEqHashCode类中equals()和hashCode()方法,测试输出结果如下:
结果分析:
我们采用HashSet构造数据,其中new RewriteEqHashCode(1001, "张三")我们构造了两次,我们认为这两次是重复的数据,第一次我们同时注释equals()和hashCode()方法测试输出结果没有去重,第二次我们启用equals()方法、注释hashCode()方法测试输出结果任然没有去重,第三次我们同时开启equals()方法、hashCode()方法测试输出结果正常去重了。
因为HashSet判断对象是否相同是根据其hashCode()值比较,而equals()默认比较也是采用hashCode()。当我们什么都不重写,默认创建的对象对应的hashCode值就是不一致的;但是当我们重写equeals()时,说明我们想更改判断对象是否相等的方式,因此我们需要同时重写hashCode(),才能保证对象判断方式是我们想要的效果。这在JDK定义equals()方法时候,注释部分也有相关说明的。
特别提示:
建议大家重写equals()、hashCode()方法时候采用IDEA编辑器自动生成的,不要自己去写,因为自己去写的往往不是很严谨。
以上代码仅供参考,如有不当之处,欢迎指出!!!
更多干货,欢迎大家关注和联系我。期待和大家一起更好的交流、探讨技术!!!
因篇幅问题不能全部显示,请点此查看更多更全内容