• 重写equals为啥需要重写hashCode


    描述

    以前一直记得重写equals要把hashCode也要重写了,但是一直也是没有搞明白,
    最近在看一些东西,觉得有必要记录一下。

    了解一下equals

    equals是Object类的方法,

    equals是干什么用的

    这个方法的作用是比较两个对象是否相等的,可能有人会问了,使用==号不就可以比较了,
    为啥非得使用equals方法呢。
    假设你有一个Student类,系统认为一个学生的学号只要相同就默认为是同一个学生,

    public class Student {
        private String IdCard;
    }
    

    如下:
    Student xiaoming=new Student("110");
    Student xm=new Student("110");
    如果使用==判断得到的结果肯定是false,因为这是两个对象,地址肯定不相同。
    如果重写equals方法

    public class Student {
        private String IdCard;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Student student = (Student) o;
    
            return IdCard != null ? IdCard.equals(student.IdCard) : student.IdCard == null;
        }
    }
    

    然后使用equals方法比较(xiaoming.equals(xm))就可以得到true。

    但是为什么非得重写hashCode方法

    因为不重写hashCode在使用Hash集合(HashMap、HashTable、HashSet)的时候会出现问题。
    如果Student类重写了equals方法没有重写hashcode方法:

    Student xiaoming=new Student("110");
    Student xm=new Student("110");
    HashMap<Student,String> map=new HashMap<Student,String>();
    map.put(xiaoming,"小明");
    map.put(xm,"小明");
    

    执行map.size() 我们想要得到的结果是:1,但是执行的结果是:2 ;
    这是因为hashmap首先比较的是两个对象的hashcode值,如果你没有重写Student类的hashCode方法,默认是按照对象内存的地址进行哈希运算得到的,这两个对象的地址肯定不一样,所以HashMap认为它不是同一个对象,就放入了集合中。
    我们添加hashCode方法的重写:

    public class Student {
        private String IdCard;
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Student student = (Student) o;
    
            return IdCard != null ? IdCard.equals(student.IdCard) : student.IdCard == null;
        }
    
        @Override
        public int hashCode() {
            return IdCard != null ? IdCard.hashCode() : 0;
        }
    }
    

    再次执行上面的代码就得到的结果就是:1;说明已经认为这两个对象是同一个了。

    建议

    大家用IDE自动生成,尽量不要自己敲因为很有可能会出错。

  • 相关阅读:
    谈对信息增益与决策树的理解
    k近邻法
    感知机相关难点细解
    点到空间中面的距离
    统计学习方法中的标注问题
    Hoeffding不等式与泛化误差上界
    经验风险与期望风险
    先验概率与后验概率
    spring和springboot常用注解总结
    多环境下读取不同的配置文件
  • 原文地址:https://www.cnblogs.com/wangsen/p/10877708.html
Copyright © 2020-2023  润新知