1、不重写hashCode和equals2、重写equals3、不重写hashCode4、重写hashCode
1、不重写hashCode和equals
定义一个People类,ID为一个People对象的唯一标识
public class People {
private String ID;//id编号唯一标识一个人,比如身份证号码
private String Name;//姓名
public People(String ID, String name) {
this.ID = ID;
Name = name;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
创建两个People对象,ID相同,按照业务理解,ID相同应为同一对象
实际输出p1和p2两个对象不相等。
public class PeopleDemo {
public static void main(String[] args) {
People p1=new People("320321199001010001","孙悟空");
People p2=new People("320321199001010001","孙悟空");
System.out.println(p1);
System.out.println(p2);
System.out.println(p1.equals(p2));//输出false
}
}
原因分析:
万物皆对象,People也不例外,它继承自ObjectPeople未重写equals方法,故会调用Object下的equals方法。
查源码可知,Object下的equals比较的是,两个对象的内存地址。
public boolean equals(Object obj) {
return (this == obj);
}
2、重写equals
上述People类中重写equals方法,如下
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
People people = (People) o;
return ID != null ? ID.equals(people.ID) : people.ID == null;
}
此时p1.equals(p2);便会返回true。
3、不重写hashCode
People只重写equals不重写hashCode的情况下。将p1、p2添加到Set对象中。Set的一个特点是存入的元素不重复下面这段代码中,输出的分别输出了p1、p2的地址,说明p1和p2都被存入了Set中
import java.util.Set;
import java.util.HashSet;
public class PeopleDemo {
public static void main(String[] args) {
People p1=new People("320321199001010001","孙悟空");
People p2=new People("320321199001010001","孙悟空");
Set set=new HashSet();
set.add(p1);
set.add(p2);
System.out.println(set);
}
}
原因分析:
Set是用哈希表实现。JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组。JDK8以后,在长度比较长的时候,底层实现了优化。未重写hashCode,会调用Object的hashCode,该hashCode根据p1、p2生成了不同的哈希码值,存入了哈希表不同的位置。
4、重写hashCode
People中重写hashCode即可解决,上述问题。
@Override
public int hashCode() {
return ID != null ? ID.hashCode() : 0;
}



