在理解这个问题时,我认为最先理解的应该是为什么会重写equals呢?理解清楚这个的前提下才有必要去理解为什么需要去重写hashcode!
为什么需要重写equals方法呢?我认为是为了适应业务场景的需求而需要对类的equals方法进行重写,最经典的重写equals方法的例子莫过于String类了,在Object类中,其equals方法即“==”,比较的是对象在内存中的地址值。而String重写了Object中的equals方法,使其变成比较String类中的各元素是否一致。
为了理解为什么在重写equals方法的时候,需要重写hashcode方法?需要拟定如下的业务场景
当我们对父类(包括Object)的equals方法重写之后,如果需要将其对象置入HashMap中的时候,由于HashMap的key是不能相同的,其判断方法是先根据HashCode方法进行判断,在HashCode方法不相等的情况下,才会通过equals方法判断两个对象是否相等。
看如下代码:
public class Person {
private String name;
Person(String name){
this.name = name;
}
@Override
public boolean equals(Object obj){
Person person = (Person) obj;
if(person.name == this.name){
return true;
}
return false;
}
public static void main(String[] args) {
HashMap<Person,String> personStringHashMap = new HashMap<Person, String>();
Person person1 = new Person("小红");
Person person2 = new Person("小红");
personStringHashMap.put(person1,"小红");
personStringHashMap.put(person2,"小黑");
System.out.println(personStringHashMap.get(person1));
System.out.println(personStringHashMap.get(person2));
}
}
我们在Person类中,重写了equals方法,其目的在于判断对象是否相等,依据的是Person类中的属性去判断两个对象是否相同,当使用了HashMap容器类的时候,发觉我们重写Person类中的equals方法的本身意义消失了。按重写equals方法的意义,将两个属性都为小红的Person类放入HashMap时,后者需要将前者覆盖,但是实际结果显示并没有覆盖本来的类,其原因在于并没有重写hashCode方法
相比较String类中,其重写equals方法时,重写了HashCode方法,其重写equals方法的意义就完美的体现出来了。下面看如下代码:
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a.equals(c));
System.out.println(a.equals(b));
HashMap hashMap = new HashMap();
hashMap.put(a,"abc");
hashMap.put(c,"bcd");
System.out.println(hashMap.get(a));
System.out.println(hashMap.get(c));
}
好了,目前的理解也只能到这儿了,如果还有不足的地方,希望可以指出