Java中的equals与==

本质区别

==

==是用于比较对象在内存中的地址的。由于Java中的变量大多都是引用变量(也就是指针),所以只有当两个变量指向同一实例化的对象时,用==才能返回true。

equals方法

equals方法则是通过该类中设计好的方法来判断两个比较的对象是否满足判等条件。例如String类中,设计的方法就是:比较每个字母,如果都一样就返回true。

对比

比如我们实例化了两个对象--->人,而且他们年龄和性别都一样。 但是他们在内存中的地址是不一样的。所以当使用==判断时,返回的值是false。但是如果设计一个equals方法,表明如果年龄一样就返回true,那么通过equals方法返回的值就是true。因为在实际问题中对于判等的需求不同,设计方法也不同。(比如设计一个员工类,只要员工ID一样就可以返回true一样)。

equals方法的设计原则

满足等价关系

等价关系有三点要求:
1.==对称性==:若x.equals(y) 返回true, 那么 y.equals(x) 也应当返回true。
2.==自反性==:对于任何非空的x,x.equals(x) 应当恒返回true。
3.==传递性==: 若x.equals(y) 返回true, y.equals(z) 返回true,那么x.equals(z)也应当返回true。

也就是说,equals返回true的前提是建立在==类相同==,==对比目标相同==的情况下的。所以在设计的时候还要先检查类型是否相同
但是对于第一点:对称性,可能你会想到,有些情况下如果要对比父类和子类该怎么办?

如果严格按照等价关系来讲,只有类完全相同才能对比。如果x是父类,y是子类。在比较时,当y.equals(x)返回true时,x.equals(y)不一定成功(因为子类可以有父类的,但是对比时,父类不一定有子类的),这样不能满足==对称性==,所以理论上是不好的

但也可以结合实际问题变通

设想这样一个场景:
有一个公司,有很多Employee,也有Manager。Manager也是雇员,所以Manager当然也是Employee的子类了。在公司里,每个员工都有自己独特的ID,这就意味着我们可以直接通过ID来判断两个员工是不是同一个人了。不过这里就与上文的==对称性==产生了冲突。但是实际情况实际考虑,这里在设计的时候就可以设计成如果是继承关系的类,也可以比较
这里可以用到instanceof关键词:

A instance of B
A是不是B的实例(A可以是B的子类或者同类)

当然,这种最好结合实际情况提前设计好呗。

代码

示列

以下是一个==严格遵循等价关系的==equals方法的写法:

public boolean equals(Object other)
{
    //这只是个优化,如果都是一个地址了必定一样了。
    if(this==other)
        return true;
    
    //检测是否为空,否则下一步会报错的
    if(other==null)
        return false;
        
    //检测类型是否完全一样    
    if(getClass()!=other.getClass())
        return false;
    
    //如果你要想父类子类比较
    //if(other instanceof this !=true)
    //  return false;   
        
    //确定了类型一样了,可以正式开始比较了
    Employee employee = (Employee)otherObject;
    
    //name是string类型,用String类型内已经写好了的euqals比较即可
    //salary是int类型,是基本类型所以可以直接用==
    return name.equals(other.name) && salary==other.salary
}

其他注意事项

覆盖

例如下面这一段代码,你能找的出问题吗(还是上面Manager和Employee的例子):

public class Manager
{
    public boolean equals(Manager other)
    {
     return other!=null
          &&this.bonus==other.bonus
          &&getClass()==other.getClass()
    }
    //Manager特有的属性--奖金bonus(int类型),普通Employee是没有的
}

这个方法声明的显式参数类型是Manager,而我们刚才在Employee类里的equals方法里声明的是Object类的参数类型。所以说,这样写出来的只是个重载,并不是重写而已。所以为了避免错误类型的发生(比如编译器傻缺偏要用Employee那个不那么精确的比较方式),所以建议加上@Override标签。

hashCode方法

hashCode与equals的定义必须一致,如果x.equals(y)返回true,那么x.hashCode()与y.hashCode()也应当具有相同的值。所以在重写了equals方法之后,最好把你在equals中对比到的属性也在hashCode中散列了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容