前言
最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题。
初步探索
首先我们要了解equals方法是什么,hashcode方法是什么。
equals方法
equals 是java的obejct类的一个方法,equals的源码如下:
-
public boolean equals(Object paramObject){
-
return(this == paramObject);
-
}
由此我们可以看到equals是用来比较两个对象的内存地址是否相等。
hashCode方法
hashCode方法是本地方法,用于计算出对象的一个散列值,用于判断在集合中对象是否重复的关键。
一条定理
equals相同的对象,hashCode必然相同。
代码示例
建立一个Student类。
-
public class Student {
-
-
private String name;
-
private int age;
-
private String QQ;
-
-
@Override
-
public boolean equals(Object o) {
-
if (this == o) return true;
-
if (o == null || getClass() != o.getClass()) return false;
-
Student student = (Student) o;
-
return age == student.age &&
-
Objects.equals(name, student.name) &&
-
Objects.equals(QQ, student.QQ);
-
}
-
}
在 student 类中,我们重写了equals方法。
书写一个测试类
-
public class Test {
-
public static void main(String[] args) {
-
Student student = new Student();
-
Student student2 = new Student();
-
System.out.println(student.equals(student2)); //true
-
System.out.println(student.hashCode()); //356573597
-
System.out.println(student2.hashCode()); //1735600054
-
HashMap<Student, String> map = new HashMap<>();
-
map.put(student,"123");
-
map.put(student2,"456");
-
System.out.println(map.get(student));
-
System.out.println(map.get(student2));
-
-
}
-
}
输出
-
true
-
356573597 student 的hashcode值
-
1735600054 student 2的hashcode值
-
123
-
456
此时,我们发现 equals 相等的对象,hashcode却不相等,同时在map中用不同的对象进行了存储,map计算出来的hash值不同,但equals却相同。这时候懵了。到底两个对象一样不一样呢。
所以我们在重写equals的时候,必须重写hashcode。
重新定义 student 类
-
public class Student {
-
-
private String name;
-
private int age;
-
private String QQ;
-
-
@Override
-
public boolean equals(Object o) {
-
if (this == o) return true;
-
if (o == null || getClass() != o.getClass()) return false;
-
Student student = (Student) o;
-
return age == student.age &&
-
Objects.equals(name, student.name) &&
-
Objects.equals(QQ, student.QQ);
-
}
-
-
@Override
-
public int hashCode() {
-
-
return Objects.hash(name, age, QQ);
-
}
-
}
再次测试
-
public class Test {
-
public static void main(String[] args) {
-
Student student = new Student();
-
Student student2 = new Student();
-
System.out.println(student.equals(student2)); //true
-
System.out.println(student.hashCode()); // 29791
-
System.out.println(student2.hashCode()); // 29791
-
HashMap<Student, String> map = new HashMap<>();
-
map.put(student,"123");
-
map.put(student2,"456");
-
System.out.println(map.get(student)); //456
-
System.out.println(map.get(student2)); //456
-
-
}
-
}
最后的输出
-
true
-
29791 //相同的对象
-
29791
-
456 //说明以一个值key存储,相同的值
-
456
几条定理
1、两个对象的equals相等,hashcode必然相等。
2、两个对象不等,hashcode也可能相等。
3、hashcode相等,对象不一定相等。
4、hashcode不等,对象一定不等。
评论(0)