zoukankan      html  css  js  c++  java
  • 帮助新手理解equals和hashCode

    入行快要两年,偶尔想起来equals和hash还是会有些晕,索性今天就更深入的弄明白一些,不足之处也请各位大神指出批评,共同进步。

    刚开始学java的时候只是记忆性的来背,如果一个类在程序中可能进行比较,那么就要重写equals和hashCode方法。但是无论如何都不能明白,而以前理解equals和hashCode都是看着eclipse工具自动生成的来理解,所以一直没看懂,觉得eclipse重写的equals和hashCode并没有 什么关系,为什么要重写。下面贴上eclipse工具重写的equals和hashCode方法进行说明

    先来看equals方法

    可以看到  第一个if判断使用this == obj  来判断,第二和第三就不用说了,第四个用的是id属性的值来用==比较,否则就返回true。 按照我以前的误解,既然这两个方法要一块重新写,那么equals就会用到hashCode才合理。 所以我想说,我们应该把equals来当做一个普通的方法来看待,不要觉得特殊,上述图片的写法只是eclipse工具的写法,如果你觉得不舒服那么就完全可以按照自己的逻辑算法来实现equals的比较逻辑只要保证equals的四原则即可。而equals和hashCode并不是相互依赖的关系。

    再看hashCode

    我们从图片中可以看到eclipse在重写hashCode方法时会让我们选择需要添加的属性,这里只用了id(因为一般的id属性是唯一的),eclipse重写的hashCode方法按照自己的算法计算除了一个值并返回给了调用者,而这个hashCode方法实际是准备给将来如果这个实体类被用到了Map或者List中来用的。下面来普及一下HashMap的数据结构

    HashMap数据结构

    我们都知道HashMap的结构是数组加链表,即每个数组元素中都是一个链表。

    存值时: 调用key的HashCode方法来计算出一个哈希值然后通过算法计算出要存放位置的数组下标(具体算法还没详细追究)。然后将key放入这个下标对应的元素中的链表中,但是如果这时候key冲突就会用equals来比较key地址所对应的value,如果value不相等那么就用链地址法来解决key冲突,如果value相等那么就会把key替换掉。所以这里就用到了HashCode以及equals,如果不重写那么就会调用Object的方法,也就是用地址比较(这是肯定不行的)。一般的我们用String类型字符串来作为key,实体类作为value,但是String类已经重写了HashCode,所以自己的类一般要重写equals,但是我们知道map中的key是可以存放对象的,当map的key存放的是自己的类的对象时,那么这时候HashCode方法就起作用了,如果不重写,那么就会导致hash值错乱。从而导致不能在map中准确的拿到数据。

    结语:

      到这里,关于equals和hashCode就讲完了。这里只是针对这两个方法的整体的思路来进行整理,有一个整体的认识,一些细节并没有提到,比如HashMap中维护的有一个transient  类型的Node来存放Hash值等。 其他的不足和错误之处也请各位大神多多批评指正。

    转载请注明出处: https://www.cnblogs.com/qiaoyutao/p/9618249.html

  • 相关阅读:
    [Golang学习笔记] 06 程序实体3 类型断言和类型转换
    [Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明
    [Golang学习笔记] 04 程序实体1 变量声明
    [Golang学习笔记] 03 库源码文件
    virgo-tomcat-server的生产环境线上配置与管理
    virgo-tomcat-server最大并发连接数的修改
    linux系统下kvm虚拟机的安装
    关于virgo-tomcat-server-3.6.0.RELEASE配置文件修改说明
    关于在Linux下apache-maven的安装
    H3C系列之三层交换机文件管理
  • 原文地址:https://www.cnblogs.com/qiaoyutao/p/9618249.html
Copyright © 2011-2022 走看看