走心解答hashCode与equals,尽量说明白

首先说结论:通过 共同使用hashcode和equals方法 来判断两个对象是否相等。

首先明确:在实际情况下,比较两个对象是否相等,我们关注的是每个对象的属性值是否都相同。

所以在比较前先要重写hashcode和equals方法。

那为什么要重写它们呢?

  • 为什么重写hashcode:因为hashcode默认是Object中的方法,默认比较的是对象的地址值(即使new出来的两个对象属性值都一样,按理说两个对象是相等的,但new出的对象之间的地址不一样),所以我们需要通过在javabean中重写hashcode方法来让其根据对象的属性值去计算对应的hashcode。
    [需要注意的是:重写过hashcode方法并不代表万事大吉不会出现问题,由于哈希冲突的存在导致,实际工作中还要结合equals去判断对象是否相等,下面会有具体解释。也可以联系集合中哈希表存储元素的过程。]
  • 为什么重写equals:而equals默认也是Object中的方法,底层使用“==”去比较对象。对于“==”我们知道:如果是基本数据类型比较的是值是否相等;如果是非基本数据类型(即引用类型)比较的是地址值是否相同。而我们在实际情况(/实际开发)中,需要比较的对象往往是引用类型的,所以需要重写equals方法去比较每个对象的各个属性值是否相同。[需要注意的是:一些包装类型和String类等,都对equals方法进行了重写,它们比较的是对象的值是否相等]

为什么要同时使用 重写后的hashcode重写后的equals 方法 共同去判断两个对象是否相等呢?

  • 如果只使用重写后的hashcode
    •         即使已经重写过,两个属性值不一样的对象,它们的hashcode也可能是一样的(哈希碰撞/哈希冲突)。【实际两个对象并不一样,所以不能只使用hashcode方法去判断 两个对象是否相等】
// eg:
String s1 = "通话";// 两个值不同的字符数组对象
String s2 = "重地";
System.out.println(s1.hashCode() == s2.hashCode());// 用重写后的hashCode去比较的结果竟然是true

String s3 = "abc";
String s4 = "acD";
System.out.println(s3.hashCode() == s4.hashCode());// true

String s5 = "3C";
String s6 = "2b";
System.out.println(s5.hashCode() == s6.hashCode());// true
  • 如果只使用重写后的equals
    •         如果不需要向底层结构是哈希表的集合中存储,只是简单比较,那么只用重写后的equals去比较两个对象是否相等完全ok。【理论可行,但实际还是建议搭配重写后的hashcode方法使用】
    •         但是,但是,如果要向底层结构是哈希表的集合中存储,就必须配合使用重写后的hashcode方法。为什么呢?因为不重写hashcode,在向底层结构是哈希表的集合中存储时,默认会去调用Object中原始的hashcode方法,虽然两个属性值一样的对象我们认为它们是相等的,但计算后得出的hashcode却不一样,按照java该系列集合的底层逻辑,这两个对象会被存储在数组的不同位置,相当于两个一样的对象存储了两次。这显然与java该系列集合的设计思想不符:对于hashset而言,不允许有重复的元素;对于hashmap而言,不允许同一个key对应多个value。

所以我们得出结论:比较两个对象是否相等,需要同时重写equals方法和hashcode方法

hashcode/哈希值/哈希码/散列码

1234

👍👍👍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值