重写equals方法为什么要重写hashcode方法
1、原因
Object 的 equals() 默认比较的是对象的内存地址,而 hashCode() 也是对对象的内存地址进行hash。
因为Hash比equals方法的开销要小,速度更快,所以在涉及到hashcode的容器中(比如HashSet),判断自己是否持有该对象时,会先检查hashCode是否相等,如果hashCode不相等,就会直接认为不相等,并存入容器中,不会再调用equals进行比较。
这样就会导致,即使该对象已经存在HashSet中,但是因为hashCode不同,还会再次被存入。因此要重写hashCode保证:如果equals判断是相等的,那hashCode值也要相等。
2、测试
场景:创建一个Product对象,认为商品id相等就是同一个对象。
(1)只重写equals方法,不重写hashcode方法
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中
虽然id相同,但是还是添加到了hashSet中。
(2)重写hashcode方法
@Override public int hashCode() { return Objects.hash(id); }
测试结果:
true // 可以看到判断是相等的 1 // 并且第二个值并没有存到HashSet中