今天看到一篇文章写为什么重写equals时必须重写hashCode方法?,洋洋洒洒7000字,给我看的头晕目眩,还是有疑问。
结果看评论一"大佬"的描述,我TMD真想给他一棒槌,关键是他讲的我也没明白。
最后看了很多文章才研究明白咋回事儿。记录一下,避免其他人踩坑。
一、直接给出答案
因为Hash比equals方法的开销要小,速度更快,所以在涉及到hashcode的容器中(比如HashSet),判断自己是否持有该对象时,会先检查hashCode是否相等,如果hashCode不相等,就会直接认为不相等,并存入容器中,不会再调用equals进行比较。
这样就会导致,即使该对象已经存在HashSet中,但是因为hashCode不同,还会再次被存入。
因此要重写hashCode保证:如果equals判断是相等的,那hashCode值也要相等
二、代码测试
- 编写一个只重写equals的实体类,不重写hashCode进行测试
我们希望只要id是一样的,就认定为是一个对象,集合中同一个对象只存一个
package com.yang.servlet;
import java.util.HashSet;
import java.util.Objects;
public class Product {
private Integer id;
private String name;
public Product(Integer id, String name) {
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;
}
// 重写equals
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Product product = (Product) o;
return Objects.equals(id, product.id);
}
public static void main(String[] args) {
Product product1 = new Product(1, "包子");
Product product2 = new Product(1, "馒头");
HashSet<Product> products = new HashSet<Product>();
products.add(product1);
products.add(product2);
// 使用equals判断是否相等
System.out.println(product1.equals(product2));
// 查看HashSet中元素个数
System.out.println(products.size());
}
}
【测试结果】
true // 可以看到判断是相等的
2 // 但是还是存到了HashSet中
- 重写hashCode,再次测试
@Override
public int hashCode() {
return Objects.hash(id);
}
【测试结果】
true // 可以看到判断是相等的
1 // 并且第二个值并没有存到HashSet中
最后修改时间:2021-11-29 15:24:49
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。