能看到这篇文章的帅哥美女们大概是疑惑一句话:为什么重写equals时必须重写hashCode方法?
我研究这个问题也是研究了好久,虽然我是个新手,但是我觉得这句话本身就不对,下面我说说我自己的理解,如果有不对的地方还望指出。
实现equals的五大原则就不谈了,相关资料有很多。直接上代码
package entity;
import java.util.Objects;
public class Item {
private String description;
private int partNumber;
public Item(String description, int partNumber) {
this.description = description;
this.partNumber = partNumber;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getPartNumber() {
return partNumber;
}
public void setPartNumber(int partNumber) {
this.partNumber = partNumber;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
return partNumber == item.partNumber &&
Objects.equals(description, item.description);
}
@Override
public int hashCode() {
return Objects.hash(description, partNumber);
}
@Override
public String toString() {
return "Item{" +
"description='" + description + '\'' +
", partNumber=" + partNumber +
'}';
}
}
IDEA自动生成的equals和hashCode方法还是普适性很高的,我们看equals方法,它是一个比较对象是否相等的方法,它里面没有任何用到hashCode方法的地方,
而hashCode方法是生成对象散列码的方法,那这个散列码在单纯的对象比较当中有什么作用呢?我认为是没有作用的。
也就是说,从Item这个类的角度来说,这两个方法是独立的,没有关联的。
但是我们换一个角度,如果我们这个类的对象,需要在散列表(HashMap,HashSet,HashTable等)中使用,那很明显,hashCode方法就会起到非常重要的作用,因为对于Item类的对象来说,本身有实现hashCode方法,比如在使用HashSet进行去重的时候,就可以先获取到散列码,如果散列码不相同,那这两个对象肯定不相等,如果散列码相同,说明产生了哈希碰撞,那就使用类的equals方法比较,看对象是不是真的相等,如果相等就去重。
所以如果要在散列表中使用Item对象,就必须实现hashCode方法,为了解决哈希碰撞的问题,也必须实现equals方法。