在不重写这两个方法时,hashcode是内存地址计算出的值,equals是用==来判断是否相同,也就是根据内存地址判断是不是相同对象。
假如我现在在开发中有一个person类,他有一些属性 如:姓名 年龄 住址。而我逻辑上需要当姓名和年龄都相同时,就认为这是同一个人,也就是同一个对象。那么肯定要重写它的equals方法
代码语言:javascript复制class Person{
String name;
String sex;
String address;
//getter setter
@Override
public boolean equals(Person p){
if(this == p) return true;
return (p.getName() == this.name && p.getSex() == this.sex);
}
}
在没有重写hashcode时,对于两个姓名、年龄都相同的person对象,hashcode肯定不同,但是equals却返回true。这里就违反了关于hashcode的约定,也会产生许多问题。
假如当我把很多person对象放入一个hashset集合中时,需要根据姓名和年龄去重。明明两个对象的姓名、年龄相同了,应该被过滤掉,但是由于在add时,两个对象的hash值不同,则不会被去重。就发生了我们认为应该被去重,但是却没有的情况,违背了设计初衷。然而在根据equals需要的属性重写hashcode方法时,保证了equals相同,hashcode一定相同,就可以避免这种错误。
代码语言:javascript复制class Person{
String name;
String sex;
String address;
//getter setter
@Override
public boolean equals(Person p){
if(this == p) return true;
return (p.getName() == this.name && p.getSex() == this.sex);
}
@Override
public int hashCode() {
return name.hashCode() sex.hashCode();
}
}
hash的好处:
假如set集合已经有一万个对象,需要挨个比较的话肯定效率特别低,而hash值就像一张每个人都有的银行卡号,在于众多对象进行比较时,只需要去判断我这个对象的hash值有没有在set中,而不需要去顺序对比,效率很高!
所以两个方法要同时重写的目的就是 要保证equals方法如果返回相同,则hashcode值一定相同