关于hashCode()和equals()的重写
拿Students举例,当一个学生姓名,年纪相同时,我们就当作时同一个学生,比如A = new Students(“张三”,“20”) B = new Students(“张三”,“20”),理论上来说这应该时同一个人,我们来看下代码的实现
Students类
public class Students {
private String name;
private String age;
public Students(){
}
public Students(String name,String age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
main方法
public class test {
public static void main(String[] args) {
Students s1 = new Students("hhh","21");
Students s2 = new Students("hhh","21");
System.out.println(s1.equals(s2)); //false
System.out.println(s1.hashCode()); //460141958
System.out.println(s2.hashCode()); //1163157884
System.out.println("============");
System.out.println(s1.getName().hashCode()); //103272
System.out.println(s2.getName().hashCode()); //103272
}
}
我们可以发现s1和s2的数值完全相同,但是equals返回值确实false,有些同学就会问了,equals不是比较两个对象中的数值是不是相同的呢,应该返回true,这是什么原因造成的呢?
实际上在Object类中,==和equals是没有区别的,对于非空的引用值,equals会先判断是否指向同一个对象,因为所有的类都是继承Object类的,拿最常用的String类来说,他是继承于Object类,但他重写了equals方法。所以我们自己写一个类的时候,如果要使用equals,就必须根据需求来重写equals方法。
重写equals方法之后的代码
Students类
public class Students {
private String name;
private String age;
public Students(){
}
public Students(String name,String age){
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o){
if(o == null){
return false;
}
if(this.getClass() != o.getClass()){
return false;
}
Students s = (Students) o;
if(s.name == null) return false;
if (age == s.getAge() && name.equals(s.getName())){
return true;
}
return false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
main方法
public class test {
public static void main(String[] args) {
Students s1 = new Students("hhh","21");
Students s2 = new Students("hhh","21");
System.out.println(s1.equals(s2)); //true
System.out.println(s1.hashCode()); //460141958
System.out.println(s2.hashCode()); //1163157884
System.out.println("============");
System.out.println(s1.getName().hashCode()); //103272
System.out.println(s2.getName().hashCode()); //103272
}
}
这时候我们发现返回值为true了,但是依照我们的理解,同一个学生的话在hash表中的位置应该是相同的,但是很明显我们看到s1和s2的hashcode方法返回值完全不一样,所以我们在这里还需要重写一下hashCode方法。一般来说,重写了equals方法都会重写hashCode方法
完整的代码
Students类
public class Students {
private String name;
private String age;
public Students(){
}
public Students(String name,String age){
this.name = name;
this.age = age;
}
@Override
public int hashCode(){
int result = name.hashCode();
result = 17 * result + age.hashCode();
return result;
}
@Override
public boolean equals(Object o){
if(o == null){
return false;
}
if(this.getClass() != o.getClass()){
return false;
}
Students s = (Students) o;
if(s.name == null) return false;
if (age == s.getAge() && name.equals(s.getName())){
return true;
}
return false;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
main方法
public class test {
public static void main(String[] args) {
Students s1 = new Students("hhh","21");
Students s2 = new Students("hhh","21");
System.out.println(s1.equals(s2)); //true
System.out.println(s1.hashCode()); //1757223
System.out.println(s2.hashCode()); //1757223
System.out.println("============");
System.out.println(s1.getName().hashCode()); //103272
System.out.println(s2.getName().hashCode()); //103272
}
}
这样我们就完成了equals方法和hashcode方法的重写啦!!!