本文主要是介绍面试题:重写equals(),为什么还要重写hashcode(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
认识equals():
Object类中的equals;
public boolean equals(Object obj) {return (this == obj);}
当我们没有重写equals(),我们是调用父类object中的方法,比较的是对象的内存地址
重写equals后,
public class Student {private int age;private String name;public Student() {}@Overridepublic 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);}
首先比较两个对象的内存地址,如果相同则返回true;
如果不相同,则比较对象的属性;对象的属性相同则返回true;
认识hashcode():
假如没有重写hashcode()通常返回的是对象内存地址取模后的哈希值
重写后:按一定的运算规则返回计算后的哈希值:通常情况下,对象相同,则返回相同的hash值
重写equals(),还要重写hashcode()的原因:
一:提高效率:考虑到 hashmap等哈希表结构中使用哈希码快速确定存储位置,方便高效;若发生hash冲突,再调用对象的equals()方法比较;
二:保持一致性:只重写equals()而没有重写hashcode();即使两个对象:x.equals(y)==true
也无法保证x.hashcode()==y.hashcode();在使用哈希表等数据结构时,无法找到正确对象从而导致一些意外;
因此既要重写equals(),又要重写hashcode();
举个例子:
Student类没有重写hashcode:
public class Student {private int age;private String name;public Student() {}@Overridepublic 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);}
}
测试类:
public static void main(String[] args) {Student s1 = new Student(18, "张三");Student s2 = new Student(18, "张三");HashMap<Student, Integer> hashMap = new HashMap<>();hashMap.put(s1,100);System.out.println("---------------");System.out.println(s1.equals(s2));System.out.println("--------------");System.out.println("s1的哈希值:"+s1.hashCode());System.out.println("s2的哈希值:"+s2.hashCode());System.out.println(hashMap.get(s2));}
结果为:
返回结果为:null
说明了即使两个对象equals()比较相同;也不能保证通过new Student(18,"张三")找到对应的value;因为s1,s2的哈希值不相同;
那么就不无法保证hashmap中元素的唯一性:因为相同的对象经过hash运算可以映射到不同槽位上,
那么就可以存储:(s1,100),s1(s1,100)
这不就是矛盾吗?
若我们重写了hashcode()方法:
@Overridepublic int hashCode() {return Objects.hash(age, name);}
输出结果为:
这篇关于面试题:重写equals(),为什么还要重写hashcode()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!