最近复习,又看到了这个问题,在此记录和整理,通过例子来说明这种情况的原因,使大家可以清晰明白这个问题。
首先我们要了解equals方法是什么,hashcode方法是什么。
equals 是java的obejct类的一个方法,equals的源码如下:
public boolean equals(Object paramObject){ return(this == paramObject); } 复制代码
由此我们可以看到equals是用来比较两个对象的内存地址是否相等。
hashCode方法是本地方法,用于计算出对象的一个散列值,用于判断在集合中对象是否重复的关键。
equals相同的对象,hashCode必然相同。
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。
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不等,对象一定不等。