没错。嘟嘟又把==号和equals 的区别给忘掉了
==号比较基本类型的时候比的是值,比较引用类型的时候比较的是地址。equals比较基本类型的时候。。。。
脑子里关于这道题的答案好模糊好没有安全感
但是请相信,看完嘟嘟这篇文章保证让你记住至少一年。记不住一年算我输。
首先==号是人家java设计之初定好的,不可能改的,更何况第一句话很好理解。就硬记吧。
至于有些人说是怎么比较基本类型的(就是关于常量池,堆内存那块的东西)嘟嘟以后有缘再研究一下。毕竟面向目的编程才是嘟嘟现在的首要目标。
然后咱们瞅瞅equals是怎么比的
首先equals不能比较基本类型
基本类型在左边??不存在的。你要是写基本类型.equals编译器不报错我直播吃水果都。
基本类型在右边??这个可以。因为嘟嘟刚才试了一下。没报错。而且debug的时候发现equals右侧的参数我就写了个1,然后就不知道被谁给自动包装成Integer类了。
所以说equals还是不能比较基本类型。
equals比较引用类型怎么比的
这个问题需要追溯到万类之爹Object 类上面。Object 类里面有一个equals方法,应该算是所有equals方法的爹。
没错,Object类里面的equals方法应该算是最原始的equals方法,比的就是地址。
然后我们再找几个其他的类看一下其他的类重写的equals 方法是怎么比较的
1.String类的 equals方法:
也就是说String 根据自己的需要(String认为什么样的比较算是两个字符串相等)重新写了equals方法。那么什么样的两个字符串才算相等呢?上面代码很明显。(1)如果地址一样,那就是相等 (2)要是地址不相等的话:如果比较的那个对象也属于String类,我就比一下两个String对象的长度。如果长度相等,我就逐个比较每一个字符。都相等??好吧。勉强算你们两个相等了。
2.咱们再看看HashMap的源代码里面是怎么定义两个HashMap相同的
上图是AbstractMap.class的equals方法嘟嘟debug了一下也证明了走的是这个equals方法
比较过程简单说一下
(1).上来先比个地址,如果地址一样,就根本不用继续往下比了。
(2) 如果比较的那个对象不属于Map这个类,那也不用继续往下比了。(这里嘟嘟先留个伏笔,后边有好玩的)
(3)如果你属于Map这个类,行,咱们比比大小吧。大小一样的话可以继续往下比
(4)到了这一步。我先将自己转化为一个一个键值对的迭代器,然后我把我的key先拿出来,问你有没有,什么?你没有?对不起,我们不合适,我们不相等。什么?你有?那你那边对应的key的value值跟我这边的一样吗?不一样?对不起,我们不合适,我们不相等。
如果上诉的条件我们都相等,我们就相等。
但是嘟嘟当时有个疑问?就是为什么上面源代码里面判断的是该对象是否属于Map类而不是按照HashMap LinkedHashMap等按照更细化的类型比较??
然后嘟嘟就做了个简单的验证:
结论就是。Map家族的设计者认为:如果两个Map对象地址不同,那只要你们键值对都一样,那我就认为你们相同,我也不管你是HashMap还是LinkedHashMap了。
进而嘟嘟有个疑问。equals方法其实是设计者们在考虑 “怎么样才算是相等” 之后,重写的Object 里面的equals 方法。那嘟嘟自己随便瞎重写一个equals方法不是也行么??嘟嘟自己尝试了(嘟嘟随便定义了一个类A ,重写了里面的equals方法,只要比较的那个对象属于String类型就算他俩相等),还特么真行。但是嘟嘟不敢保证以后你瞎写一个equals方法你项目经理打不打你。
所以嘟嘟下面要说的就是重写equals方法要遵守的几个原则
1.自反性:自己跟自己比一定要相等。像嘟嘟自己写的那个就不相等。
2. 对称性:a.equals(b)和b.equals(a)必须返回的是同结果。(HashMap和LinkedHashMap对象相互比较的时候也是满足对称性的,因为HashMap和linkedHashMap的equals方法用的都是AbstractMap的)
3.传递性:a等于b,b等于c,那么a也等于c
4.一致性:如果a和b没改变,多次调用equals方法得到的结果相同
大总结:
==号基本类型比较数值,引用类型比较地址
equals 如果是Object类的equals 比较的就是地址(用的==号啊)
但是不同的类,可能重新写了自己的equals方法(这里举一个String的一个Map就行了吧)
但是equals 在设计的时候要遵守4个原则 (自反,对称,传递,一致)
原文地址:https://www.cnblogs.com/ruishui30005921/p/11258479.html