为什么要重写hashCode方法

说清为什么要重写hashcode方法

hashCode()到底有什么用,为啥一定要和equals()重写

HashCode()是native方法,重写后,会把HashCode()转换成int数值返回

int数值返回的就是哈希码,也称散列码 .  作用就是确定对象在哈希表的索引位置

哈希表 :JDK8 之后 是 数组 +链表 +红黑树

例子 : 有一万+ 的对象,需要存储起来,不允许存储重复的对象并且可以随时获取对象. 怎么做?

        可能有的朋友想到数组存储,当把对象放在数组中,每判断一次,都需要遍历数组,挨个比较,使用equals ,如果equals为真,就找到了对象,如果为false,就是假.但是这样子的效率太低.时间复杂度O(n)

        怎么样提高效率.使用hashCode得到的哈希码就派上了用场.  通过哈希码和数组长度取余,这样子就得到了数组要存放的位置 .  例如,数组长度是10,哈希值为17,就把这个对象放在数组下标为7的位置上.这样子无论是获取元素还是存储元素,通过数组下标只需要操作一次.时间复杂度为O(1) ..  确定索引位置就可以大幅度提高效率

        还有一个很大的问题.哈希码是可能重复的,哈希值是根据一定的逻辑计算出来的int值,两个不同的对象可能重复哈希码.就这就哈希冲突. 

        如果发生Hash冲突时,我们要先比较两个对象的是否相同,如果相同,就是重复元素,就不需要存储了.  如果不相等, 就要想办法把两个哈希冲突的元素存储起来

        怎么判断两个对象是否相等,肯定使用equals方法

        hashcode方法定位索引位置,equals方法判断两个对象是否相等. hashcode虽然效率高,但是会发生哈希冲突.当哈希冲突时,就要通过equals方法来判断对象是否相等

        如果只重写了HasCode方法,当发生哈希冲突时,即两个对象相等,也不会判定重复,会导致数组里面存储一大堆重复对象

        (解释 : 两个相同的对象,计算出的哈希值一样,会放到一个数组里面,这样会有很多的重复对象.重复的对象,违背了不可重复key具有唯一性,这样子肯定是不行的)

        如果只重写了equals方法,两个相等的对象,内存地址还是不会相等,还是会存在重复元素的问题.所以两个方法最好都重写

        (解释 : 重新了equals方法,你new了两个相同的对象,内存地址肯定是不相同的, 那么放到集合里面,会认为是不一样的数据, 还是可能会放到同一个数组里面,这样子还是会导致元素重复)     

总结: hashcode 和 equals 

        hashcode 方法 用来在最快时间判断两个对象是否相等,并定位索引位置,不过可能会出现误差

       equals 方法 判断两个对象是否绝对相等

        hashcode方法保证性能, equals方法保证可靠

        

一些问题及解决

问题  : hashcode相同的话旧的数据不应该是被覆盖,为什么会存储大量重复数据呢

            假设一批对象属性值一模一样,重写了hashCode没重写equals方法,那hashCode就会相同,但equals不相同,就会判定这些对象都不相等,进而不会覆盖,会将这一批对象都存储起来

集合里面有哪些不可重复的

HashSet : 底层是哈希表的数据结构,无序不可重复

LinkedHashSet: 底层是双向链表+哈希表 . 有序不可重复

Map集合的key都是不可重复的 如果key重复的话,数据就会覆盖

如果要保证不重复,必须得要保证key的唯一性

        

    

  • 43
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值