zoukankan      html  css  js  c++  java
  • 重写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自动生成,尽量不要自己敲因为很有可能会出错。

  • 相关阅读:
    不要同时使用ReentrantLock类与synchronized关键字锁定会修改同一个资源的不同方法
    java中volatile关键字的含义
    浅谈操作系统对内存的管理
    Java线程池使用说明
    写在清明节之后
    PY一天一学
    24小时只睡了1个小时
    关于团队关于吐槽
    出尔反尔
    时间都去哪儿了?
  • 原文地址:https://www.cnblogs.com/wangsen/p/10877708.html
Copyright © 2011-2022 走看看