一.什么情况下需要重写equals方法?
1.正常情况下,Java的基本数据类型和包装数据类型都已经重写的Object类的equals方法和hashCode方法
需要重写equals方法的场景:主要依据我们的业务场景来看,例如:当我们对Coder这个对象进行判断的时候,我们不需要Coder的所有的属性都必须相同,则可以重写Coder的equals方法,和hashCode()方法,达到只判断Coder的name相同即为对象相同,而不需要考虑其他的age等属性是否相同.
public void hashCodeTest() {
Coder coder = new Coder("lxyer", 22);
Coder coder1 = new Coder("lxyer1", 221);
Coder coder2 = new Coder();
coder2.setAge(222);
coder2.setName("lxyer");
System.out.println(coder.hashCode());
System.out.println(coder1.hashCode());
System.out.println(coder2.hashCode());
System.out.println(coder.equals(coder2));
Set set = new HashSet();
set.add(coder);
set.add(coder1);
set.add(coder2);
System.out.println(set.size());
}
@Data
public class Coder {
private String name;
private int age;
public Coder() {
}
public Coder(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (o==null) {
return false;
}
if (o==this) {
return true;
}
if (o.getClass()!=this.getClass()) {
return false;
}
Coder other = (Coder) o;
if (other.getName()==this.getName()) {
return true;
}
return false;
}
@Override
public int hashCode() {
//hash使用素数
int hash = 17;
return hash*31+getName().hashCode();
}
}
//输出结果为:
103435241
103435241
103435241
true
1
2.已经实现了我们想要的目的:只考虑name属性是否相同,不考虑age属性的异同来判断Coder对象是否相等.
二.为什么一定需要重写hashcode方法?
1.我们把重写的hashcode方法注释掉之后,对两个new Coder(“lxyer”,22)对象就行获取hashCode,得到的两个hash值完全不同,因为没有重写hashCode方法,会使用Object的hashCode方法,是依据对象的内存地址进行hash算法取得的值.
2.不重写hashCode方法,如果我们进行equals判断两个对象是否相等的时候,明明两个对象所有的属性都相同,但是内存地址不同,进而两个对象的hashCode也不同,在使用HashMap,HashSet等需要依赖hash值的数据结构时,就会出现相同的对象因hash值不同,储存到了不同的哈希槽中,产生了错误的结果.
//把重写的hashcode方法注释掉之后的结果
1681215776
1689723487
870019773
true
3