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自动生成,尽量不要自己敲因为很有可能会出错。

  • 相关阅读:
    Js获取当前日期时间及其它操作
    c# 扩展方法奇思妙用
    SQL、LINQ、Lambda 三种用法(转)
    jquery的$.extend和$.fn.extend作用及区别.txt
    asp.net中virtual和abstract的区别
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句.txt
    顺序结构的数据链表,仍旧薄弱(照着大了一边)
    verilog的移位运算符(存在不公平现象)
    在强制类型转话的时候,本来是不对的,但是加上引用符号后就变得正确,为什么?(未解决)
    c语言中的结构体
  • 原文地址:https://www.cnblogs.com/wangsen/p/10877708.html
Copyright © 2011-2022 走看看