关于“==”、equals()、hashCode()

本文深入探讨Java中字符串比较的两种方式——相等性比较(==)与equals()方法,解释了它们的区别及作用。同时,阐述了字符串在创建过程中如何在String Pool和堆中维护,以及equals()方法的设计目的。进一步解读hashCode()函数及其与equals()函数之间的关系,最后通过实例展示了HashSet、HashMap等集合对象的工作原理。
1.相等性比较(==)
1)  对于原生数据类型来说,比较的是左右两边的值是否相等。 
2)  对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两
边的引用地址是否相同。 
2. equals()方法
该方法定义在Object类当中,因此Java中的每个类都具有该方法,
对于Object类的equals()方法来说,它是判断调用equals()方法的引用与传进来的引
用是否一致,即这两个引用是否指向的是同一个对象。对于Object类的equals()方
法来说,它等价于==。 
3.对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容
是否一致。

4.关于字符串
字符串在创建的过程中,由jvm维护着一个字符串池(String Pool)
String s = “aaa”;(采用字面值方式赋值),创建过程如下
    1)  查找String Pool中是否存在“aaa”这个对象,如果不存在,则在String Pool中创建
        一个“aaa”对象,然后将String  Pool中的这个“aaa”对象的地址返回来,赋给引
        用变量s,这样s会指向String Pool中的这个“aaa”字符串对象 
    2)  如果存在,则不创建任何对象,直接将String Pool中的这个“aaa”对象地址返回来,
        赋给s引用。
String s = new String(“aaa”); 创建过程如下
    1)  首先在String Pool中查找有没有“aaa”这个字符串对象,如果有,则不在String Pool
        中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对
        象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中
        创建的这个“aaa”字符串对象。 
    2)  如果没有,则首先在String Pool中创建一个“aaa“对象,然后再在堆中(heap)创
        建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给s 引用,
        导致s指向了堆中所创建的这个”aaa“对象。 
5.设计equals()方法的目的其实就是为了比较对象的内容是否一样
Java语言对equals()的要求如下,这些要求是必须遵循的。否则,你就不该浪费时间:
对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
反射性:x.equals(x)必须返回是“true”。
类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。
关于hashCode():
这个函数返回的就是一个用来进行hash操作的整型代号,请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的Collection对象中的位置。这些对象是HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须自己设计,用来协助HashMap, Hashtable, HashSet,等等对自己所收集的大量对象进行搜寻和定位。

这些Collection对象究竟如何工作的,想象每个元对象hashCode是一个箱子的 编码,按照编码,每个元对象就是根据hashCode()提供的代号归入相应的箱子里。所有的箱子加起来就是一个HashSet,HashMap,或 Hashtable对象,我们需要寻找一个元对象时,先看它的代码,就是hashCode()返回的整型值,这样我们找到它所在的箱子,然后在箱子里,每 个元对象都拿出来一个个和我们要找的对象进行对比,如果两个对象的内容相等,我们的搜寻也就结束。这种操作需要两个重要的信息,一是对象的 hashCode(),还有一个是对象内容对比的结果。

hashCode()的返回值和equals()的关系如下:
如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

为什么这两个规则是这样的,原因其实很简单,拿HashSet来说吧,HashSet可以拥有一个或更多的箱子,在同一个箱子中可以有一个 或更多的独特元对象(HashSet所容纳的必须是独特的元对象)。这个例子说明一个元对象可以和其他不同的元对象拥有相同的hashCode。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。(在实际的某个集合对象如HashSet set.contains(object o);时,是先通过 hashcode()找到“箱子” ,在根据equals判断对象内容 是否相等,从而判断集合对象是否包含某个元对象)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值