• 【为什么重写equals后还需要重写hashcode】


    为什么重写equals还要重写hashcode
     
     
    一些资料上都会提到,“重写equals时也要同时覆盖hashcode”;
    •  先简述一下HashMap的原理
        hashmap在jdk8后采用数组+链表+红黑树的数据结构。我们通过put和get存储和获取对象。当我们给put()方法传递键和值时,先对键做一个hashCode()的计算来得到它在bucket数组中的位置来存储Entry对象。当获取对象时,通过get获取到bucket的位置,再通过键对象的equals()方法找到正确的键值对,然后在返回值对象。
     
    •   HashMap存储数据的时候,是取的key值的哈希值,然后计算数组下标,再通过哈希函数计算存储地址
    哈希函数构造方法有:(直接定址法,数字分析法,平方取中法,折叠法,除留余数法,随机数法等等),其中除留余数法是最常用的,也是最合理的。
    如果通过哈希函数计算得出的存储地址相同,称为哈希冲突,也叫哈希碰撞,
    Hash解决冲突的方法: 开放定址法,再散列函数法,链地址法。其中开放定址法又包括(主要是:线性探测法,二次探测法,伪随机探测法)
    而HashMap即是采用了链地址法,也就是数组+链表的方式,
     
    • 其采用链地址法解决冲突,然后进行存储;取数据的时候,依然是先要获取到哈希值,找到数组下标,然后for遍历链表集合,进行比较是否有对应的key。
    1. 无论是 put 还是 get 的时候,都需要得到key的哈希值,去定位key的数组下标;
    2. 在 get 的时候,需要调用equals方法比较是否有相等的key存储过  引用 https://www.imooc.com/article/280580?block_id=tuijian_wz

    第二点解释了为什么我们需要重写equals,==只是比较地址,并不能确认是否有相同的key,不重写的话上一个 话题也提到了,会返回false,所以需要重写equals

    那么为什么重写equals后还要重写hashcode?

    由于在hashMap中在put 时,散列函数根据它的哈希值找到对应的位置,如果该位置有元素,首先会使用hashCode方法判断,如果没有重写hashCode方法,那么即使俩个对象属性相同hashCode方法也会认为他们是不同的元素(另外key值相同却被认为是不同,所以会出现相同的key,而map规定不应该出现重复key),又因为Set是不可以有重复的,所以这会产生矛盾,那么就需要重写hashCode方法

    或者说,由于没有重写hashCode方法,所以put操作时,key(hashcode1)–>hash–>indexFor–>最终索引位置 ,而通过key取出value的时候 key(hashcode1)–>hash–>indexFor–>最终索引位置,由于hashcode1不等于hashcode2,导致没有定位到一个数组位置而返回逻辑上错误的值null。

    此段引用:https://www.cnblogs.com/chengxiao/p/6059914.html

    一句话,如果不重写hashcode方法,任何对象的hashcode值都不相等(即使逻辑上key相同,我们希望它显示相等时,结果依然是不等)

  • 相关阅读:
    8种CSS清除浮动的方法优缺点分析
    link和@import的区别
    删除表及删除表中数据的方法
    【HTML5】---【HTML5提供的一些新的标签用法以及和HTML 4的区别】
    【HTML】---HTML语义化
    【HTML5】页面点击按钮添加一行 删除一行 全选 反选 全不选
    第四篇:python 高级之面向对象初级
    第三篇:python高级之生成器&迭代器
    第二篇:python高级之装饰器
    第一篇:python高级之函数
  • 原文地址:https://www.cnblogs.com/dabuliu/p/14433243.html
Copyright © 2020-2023  润新知