暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

面试官:为什么重写equals时必须重写hashCode方法?

一叶扁舟 2021-04-06
9933

image.png

今天看到一篇文章写为什么重写equals时必须重写hashCode方法?,洋洋洒洒7000字,给我看的头晕目眩,还是有疑问。
结果看评论一"大佬"的描述,我TMD真想给他一棒槌,关键是他讲的我也没明白。

image.png

最后看了很多文章才研究明白咋回事儿。记录一下,避免其他人踩坑。

一、直接给出答案

因为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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论