java中的hashcode()与equals()

本文以HashSet为例,描述在hash数据结构中使用类时,类必须同时实现hashcode()方法与equals()方法的原因,有描述不准确的地方,还请不吝指正。



有一个Student类,类有属性:id和phonenumber,id是唯一的,每个同学有一个唯一的id.
用一个HashSet存放班上所有的同学,在同学的电话号码变化后,采用set.add(new Student(id,newPhoneNumber))的方式
覆盖之前的学生记录,达到更新同学电话号码的目的。(当然,也可以从set中取到对应ID的Student对象再修改电话号码,此处采用直接用新实例覆盖的方式,便于说明hashcode()和equals()的作用)

要采用直接set.add()的方式更新学生电话号码,就必须在Student类中,以id为基准,重载hashCode()和equals()方法,即只要id相同,equals()方法就返回true;hashcode()方法产生code时只以id为基准产生。否则,set中就可能存在多个id相同的student对象。


原因是:(以拉链法解决冲突的hash表为例)

hashset.add(student),需要通过对象student的hashcode值查找其指向的链表,之后,再通过equals()方法在链表中找equals()查找是否有equals()返回为true的对象。
若对象student的hashcode无对应链表,hash表中新增code及对应链表,链表中存储student对象。
若对象student的hashcode有对应链表,但在链表中未找到equals()返回为true的对象,则将student对象插入该链表。
若对象student的hashcode有对应链表,且存在equals()返回为true的对象,则将该对象更换为student。

如果Student类不实现hashcode()方法,则使用Object的hashcode()方法产生对象的hashcode值,该值是通过对象的内存地址算出来的,是唯一的。
此种情况下,每一个Student类对象的hashcode值都是不一样的,那么即使在Hashset中存在id相同的student对象,也无法找到,
采用set.add(new Student(id,newPhoneNumber))方式,就无法覆盖相同id的对象。
如果不实现equals()方法,则使用Object的equals()方法,即使用对象的内存地址比对是否为同一对象。
同理,new出来的id相同的student对象,其equals()不会为true,采用set.add(new Student(id,newPhoneNumber))方式,也就无法覆盖相同id的对象。

因此,若要在Hash数据结构中,比如HashSet,HashMap中存储对象,该对象必须重载hashcode()方法和equals()方法。


由于hashcode()方法实现不好,会导致hash值冲突,以拉链法解决冲突的hash表为例,极端情况下会导致成为单链表,降低hash查找效率。
因此,可采用eclipse中自动生成hashcode()的方法:"Source"->"Generate HashCode() And equals()",然后选择要判重的对象属性,点击"OK",就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值