前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java-equals为啥要重写

Java-equals为啥要重写

原创
作者头像
笔头
修改2022-03-02 18:01:54
6040
修改2022-03-02 18:01:54
举报
文章被收录于专栏:Android记忆

一、场景

equals在我们代码经常看到,用来比较值或者对象是否相等,有时我们还用 "==" 这个符号来比较。我们知道 "==" 符号是指对内存地址进行比较,而equals除了比较地址还比较值,我们来看下equals源码。

代码语言:javascript
复制
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = length();
        if (n == anotherString.length()) {
            int i = 0;
            while (n-- != 0) {
                if (charAt(i) != anotherString.charAt(i))
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

我们可以很清晰的看出,equals这个方法,第一步就是比较两个变量地址,如果地址是同一个,那就表示他们相同。如果不相同,那就看他们是不是String类型,如果是的话,就比较他们字符串是否相同。

从这也能看出,我们在比较两个变量时,不管是String还是其他类型变量,用equals比较合适。

二、为什么要重写equals

上面代码我们可以看到,不同内存地址的两个对象不可能相等,哪怕这两个对象数据一样。我们来个实例。

这两个Person相等吗?看上面equals源码,不相等。但是按照现实,他们身份证Id相同、名字相同、年龄一样,那就是同一个人哈。

这个时候我们就要重写equals方法了。我们不应该比较他们内存地址,而是比较他们内部字段数据,身份证Id、名字、年龄。代码如下。

代码语言:javascript
复制
@Override
public boolean equals(@Nullable @org.jetbrains.annotations.Nullable Object obj) {
    if(obj==null)
        return false;
    if(this==obj)
        return  true;
    if(obj instanceof Person){
        Person objTemp=(Person)obj;
        if(objTemp.Id.equals(this.Id)&&objTemp.name.equals(this.name)&&objTemp.age.equals(this.age))
            return  true;
    }
    return false;
}

这里就是简单写一下,清楚意思就好。

这样我们才能判断两个Person是不是相同。

三、重写注意点hashCode

上面我们清楚了为什么以及如何重写equals,但是这里有个注意点,那就是hashCode。在我们存储变量数据时,hashCode是一个很重要的判断比较的标准,比如HashSet,有兴趣的同学可以看下这篇文章。当我们把Person变量存储在HashSet的时候,HashSet会对变量hashCode进行比较,我们来看下HashSet源码片段

这个是HashMap中的putVal源码,hashSet.add方法最终会调用此方法。我们可以看到红框代码,如果hash表中原有的变量hash值和新增的变量hash值一样,那就直接替换旧值。

如果hashCode不重写,每个Person即使内部数据一样,但是hash值不一样,在同一个hashset表中,就会出现重复存储。这个时候我们就要重写hashCode方法,让内部数据一样的Person的hashCode也一样。

hashCode方法重写和equals差不多

代码语言:javascript
复制
    @Override
    public int hashCode() {
        int result = 10;
        result = 31 * result + (Id == null ? 0 : Id.hashCode());
        result = 31 * result + (name == null ? 0 : name.hashCode());
        result = 31 * result + (age == null ? 0 : age.hashCode());
        return result;
    }
}

result=10是随便取值的,就是一个简单初始值,没有其他含义。

31这个值,是参考String hashCode源码中取的值,这个值,网上有各种解析和猜测,可以网上查查。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、场景
  • 二、为什么要重写equals
  • 三、重写注意点hashCode
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档