zoukankan      html  css  js  c++  java
  • 重写java类的equals()和hashCode方法

    一、equals()方法和hashCode()方法是什么?
    equals()和hashCode()都是是Java中万物之源Object类中的方法;
    equals方法用于比较两个对象是否相同,Object类中equals方法的实现是比较引用地址来判断的对象是否是同一个对象,通过覆盖该方法可以实现自定义的判断规则;
    hashCode是jdk根据对象的地址或者字符串或者数字计算该对象的哈希码值的方法。
    二、为什么要重写equals()方法?
    Object类中equals方法比较的是两个对象的引用地址,只有对象的引用地址指向同一个地址时,才认为这两个地址是相等的,否则这两个对象就不想等。
    如果有两个对象,他们的属性是相同的,但是地址不同,这样使用equals()比较得出的结果是不相等的,而我们需要的是这两个对象相等,因此默认的equals()方法是不符合我们的要求的,这个时候我们就需要对equals()方法进行重写以满足我们的预期结果。
    在java的集合框架中需要用到equals()方法进行查找对象,如果集合中存放的是自定义类型,并且没有重写equals()方法,则会调用Object父类中的equals()方法按照地址比较,往往会出现错误的结果,此时我们应该根据业务需求重写equals()方法。
    三、为什么要重写hashCode()方法?
    hashCode()方法用于散列数据的快速存储,HashSet/HashMap/Hashtable类存储数据时都是根据存储对象的hashcode值来进行分类存储的,一般先根据hashcode值在集合中进行分类,在根据equals()方法判断对象是否相同。
    HashMap对象是根据其Key的hashCode来获取对应的Value。
    生成一个好的hashCode值能提高HashSet查找的性能,差的hashCode值不但不能提高性能,甚至可能造成错误。比如hashCode方法中返回常量,会让,HashSet的查找效率退化为List集合的查找效率;hashCode方法中返回随机数,会让查找结果变的不可预测。
    好的hashCode生成方式是让对象中的关键属性与质数相乘,并将积相加获取。
     
     
    四、为什么java中在重写equals()方法后必须对hashCode()方法进行重写?
    为了维护hashCode()方法的equals协定,该协定指出:如果根据 equals()方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode方法都必须生成相同的整数结果;而两个hashCode()返回的结果相等,两个对象的equals()方法不一定相等。
    HashMap对象是根据其Key的hashCode来获取对应的Value。
    在重写父类的equals()方法时,也重写hashcode()方法,使相等的两个对象获取的HashCode值也相等,这样当此对象做Map类中的Key时,两个equals为true的对象其获取的value都是同一个,比较符合实际。
     
    Person类代码如下
    Person{
    private int id;
    private String name;
    private String sex;
    
    省略get set
    
    @Override
    public boolean equals(Object o) {
    //自反性
    if (this == o) return true;
    //对象为空,则不往下走了 
    if (o == null)    return false ; 
    
    //任何对象不等于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());
    }
    
    @Override
        public int hashCode() {
            int result = name.hashCode();
            result = 17 * result + sex.hashCode();
            result = 17 * result + id.hashCode();
            return result;
        }
    }
    五、hashcode里的代码该怎么理解?该如何写?

    其实有个相对固定的写法,先整理出你判断对象相等的属性,然后取一个尽可能小的正整数(尽可能小时怕最终得到的结果超出了整型int的取数范围),这里我取了17,(好像在JDK源码中哪里看过用的是17),然后计算17*属性的hashcode+其他属性的hashcode,重复步骤

  • 相关阅读:
    对于Dubbo一些面试题自己的答案
    序列化和反序列化的简单理解
    学习Spring-Session+Redis实现session共享
    Java中的String,StringBuilder,StringBuffer三者的区别
    个人对数据结构的理解和总结
    LeetCode 101. Symmetric Tree
    LeetCode 100. Same Tree
    LeetCode 88. Merge Sorted Array
    LeetCode 83. Remove Duplicates from Sorted List
    LeetCode 70. Climbing Stairs
  • 原文地址:https://www.cnblogs.com/lhq1996/p/13254923.html
Copyright © 2011-2022 走看看