zoukankan      html  css  js  c++  java
  • 【为什么重写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相同,我们希望它显示相等时,结果依然是不等)

  • 相关阅读:
    Docker之Linux UnionFS
    Docker之Linux Cgroups
    Docker之Linux Namespace
    理解Docker容器的进程管理
    Docker命令详解
    协同过滤和基于内容推荐有什么区别?
    Docker 有什么优势?
    kubernetes
    Docker如何为企业产生价值?
    关于网页的几种高度说明
  • 原文地址:https://www.cnblogs.com/dabuliu/p/14433243.html
Copyright © 2011-2022 走看看