java重写equals()方法和hashCode()方法

1.equals()方法和hashCode()方法是什么?java

    equals()和hashCode()都是是Java中万物之源Object类中的方法;
    equals方法用于比较两个对象是否相同,Object类中equals方法的实现是比较引用地址来判断的对象是不是同一个对象,经过覆盖该方法能够实现自定义的判断规则;
    hashCode是jdk根据对象的地址或者字符串或者数字计算该对象的哈希码值的方法。程序员

2.为何要重写equals()方法?框架

    Object类中equals方法比较的是两个对象的引用地址,只有对象的引用地址指向同一个地址时,才认为这两个地址是相等的,不然这两个对象就不想等。
    若是有两个对象,他们的属性是相同的,可是地址不一样,这样使用equals()比较得出的结果是不相等的,而咱们须要的是这两个对象相等,所以默认的equals()方法是不符合咱们的要求的,这个时候咱们就须要对equals()方法进行重写以知足咱们的预期结果。
    在java的集合框架中须要用到equals()方法进行查找对象,若是集合中存放的是自定义类型,而且没有重写equals()方法,则会调用Object父类中的equals()方法按照地址比较,每每会出现错误的结果,此时咱们应该根据业务需求重写equals()方法。ide

3.为何要重写hashCode()方法?性能

    hashCode()方法用于散列数据的快速存储,HashSet/HashMap/Hashtable类存储数据时都是根据存储对象的hashcode值来进行分类存储的,通常先根据hashcode值在集合中进行分类,在根据equals()方法判断对象是否相同。
    HashMap对象是根据其Key的hashCode来获取对应的Value。
    生成一个好的hashCode值能提升HashSet查找的性能,差的hashCode值不但不能提升性能,甚至可能形成错误。好比hashCode方法中返回常量,会让,HashSet的查找效率退化为List集合的查找效率;hashCode方法中返回随机数,会让查找结果变的不可预测。
    好的hashCode生成方式是让对象中的关键属性与质数相乘,并将积相加获取。this

4.为何java中在重写equals()方法后必须对hashCode()方法进行重写?编码

    为了维护hashCode()方法的equals协定,该协定指出:若是根据 equals()方法,两个对象是相等的,那么对这两个对象中的每一个对象调用 hashCode方法都必须生成相同的整数结果;而两个hashCode()返回的结果相等,两个对象的equals()方法不必定相等。
    HashMap对象是根据其Key的hashCode来获取对应的Value。
    在重写父类的equals()方法时,也重写hashcode()方法,使相等的两个对象获取的HashCode值也相等,这样当此对象作Map类中的Key时,两个equals为true的对象其获取的value都是同一个,比较符合实际。.net

5.重写equals()方法:code

重写equals方法须要遵循Java以下规则,不然编码行为会难以揣测:对象

    自反性:对于任意的对象x,x.equals(x)返回true(本身必定等于本身);
    对称性:对于任意的对象x和y,若x.equals(y)为true,则y.equals(x)亦为true;
    传递性:对于任意的对象x、y和z,若x.equals(y)为true且y.equals(z)也为true,则x.equals(z)亦为true;
    一致性:对于任意的对象x和y,x.equals(y)的第一次调用为true,那么x.equals(y)的第二次、第三次、第n次调用也均为true,前提条件是没有修改x也没有修改y;
    对于非空引用x,x.equals(null)永远返回为false。

重写代码以下:


    @Override
    public boolean equals(Object o) {
        //自反性
        if (this == o) return true;
        //任何对象不等于null,比较是否为同一类型
        if (!(o instanceof Person)) return false;
        //强制类型转换
        Person person = (Person) o;
        //比较属性值
        return getId() == person.getId() &&
                Objects.equals(getName(), person.getName()) &&
                Objects.equals(getSex(), person.getSex());
    }

 

6.重写hashCode()方法:

HashMap对象是根据其Key的hashCode来获取对应的Value。
在重写父类的equals方法时,也重写hashcode方法,使相等的两个对象获取的HashCode也相等,这样当此对象作Map类中的Key时,两个equals为true的对象其获取的value都是同一个,比较符合实际。

重写hashCode()方法须要遵循hashCode()协定:

    一致性:在Java应用程序执行期间,在对同一对象屡次调用hashCode方法时,必须一致地返回相同的整数,前提是将对象进行hashcode比较时所用的信息没有被修改。
    equals:若是根据equals()方法比较,两个对象是相等的,那么对这两个对象中的每一个对象调用hashCode()方法都必须生成相同的整数结果,注:这里说的equals()方法是指Object类中未被子类重写过的equals()方法。
    附加:若是根据equals()方法比较,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode方法不必定生成不一样的整数结果。可是,程序员应该意识到,为不相等的对象生成不一样整数结果能够提升哈希表的性能。

重写代码以下:


    @Override     public int hashCode() {         return Objects.hash(getId(), getName(), getSex());     }

相关文章
相关标签/搜索