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,重复步骤

  • 相关阅读:
    [算法] 堆栈
    [刷题] PTA 02-线性结构3 Reversing Linked List
    java IO流 (八) RandomAccessFile的使用
    java IO流 (七) 对象流的使用
    java IO流 (六) 其它的流的使用
    java IO流 (五) 转换流的使用 以及编码集
    java IO流 (四) 缓冲流的使用
    java IO流 (三) 节点流(或文件流)
    java IO流 (二) IO流概述
    java IO流 (一) File类的使用
  • 原文地址:https://www.cnblogs.com/lhq1996/p/13254923.html
Copyright © 2011-2022 走看看