解析Java对象的equals()和hashCode()的使用

前言

在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况 下,这两个函数是不用考虑的,直接使用它们的默认设计就可以了。但是在一些情况下,这两个函数最好是自己设计,才能确保整个程序的正常运行。最常见的是当 一个对象被加入收集对象(collection object)时,这两个函数必须自己设计。更细化的定义是:如果你想将一个对象A放入另一个收集对象B里,或者使用这个对象A为查找一个元对象在收集对 象B里位置的钥匙,并支持是否容纳,删除收集对象B里的元对象这样的操作,那么,equals()和hashCode()函数必须开发者自己定义。其他情 况下,这两个函数是不需要定义的。

equals():

它是用于进行两个对象的比较的,是对象内容的比较,当然也能用于进行对象参阅值的比较。什么是对象参阅值的比较?就是两个参阅变量的值得比较,我们 都知道参阅变量的值其实就是一个数字,这个数字可以看成是鉴别不同对象的代号。两个对象参阅值的比较,就是两个数字的比较,两个代号的比较。这种比较是默 认的对象比较方式,在Object这个对象中,这种方式就已经设计好了。所以你也不用自己来重写,浪费不必要的时间。

对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求如下,这些要求是必须遵循的。否则,你就不该浪费时间:

对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。

反射性:x.equals(x)必须返回是“true”。

类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。

还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。

任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

hashCode():这 个函数返回的就是一个用来进行赫希操作的整型代号,请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的收集对象中的位置。这些对象是HashMap, Hashtable, HashSet,等等。这个函数和上面的equals()函数必须自己设计,用来协助HashMap, Hashtable, HashSet,等等对自己所收集的大量对象进行搜寻和定位。

这些收集对象究竟如何工作的,想象每个元对象hashCode是一个箱子的 编码,按照编码,每个元对象就是根据hashCode()提供的代号归入相应的箱子里。所有的箱子加起来就是一个HashSet,HashMap,或 Hashtable对象,我们需要寻找一个元对象时,先看它的代码,就是hashCode()返回的整型值,这样我们找到它所在的箱子,然后在箱子里,每 个元对象都拿出来一个个和我们要找的对象进行对比,如果两个对象的内容相等,我们的搜寻也就结束。这种操作需要两个重要的信息,一是对象的 hashCode(),还有一个是对象内容对比的结果。

hashCode()的返回值和equals()的关系如下:

如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。

如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

为什么这两个规则是这样的,原因其实很简单,拿HashSet来说吧,HashSet可以拥有一个或更多的箱子,在同一个箱子中可以有一个 或更多的独特元对象(HashSet所容纳的必须是独特的元对象)。这个例子说明一个元对象可以和其他不同的元对象拥有相同的hashCode。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。

设计这两个函数所要注意到的:

如果你设计的对象类型并不使用于收集性对象,那么没有必要自己再设计这两个函数的处理方式。这是正确的面向对象设计方法,任何用户一时用不到的功能,就先不要设计,以免给日后功能扩展带来麻烦。

如果你在设计时想别出心裁,不遵守以上的两套规则,那么劝你还是不要做这样想入非非的事。我还没有遇到过哪一个开发者和我说设计这两个函数要违背前面说的两个规则,我碰到这些违反规则的情况时,都是作为设计错误处理。

当一个对象类型作为收集型对象的元对象时,这个对象应该拥有自己处理equals(),和/或处理hashCode()的设计,而且要遵守前面所说 的两种原则。equals()先要查null和是否是同一类型。查同一类型是为了避免出现ClassCastException这样的异常给丢出来。查 null是为了避免出现NullPointerException这样的异常给丢出来。

如果你的对象里面容纳的数据过多,那么这两个函数 equals()和hashCode()将会变得效率低。如果对象中拥有无法serialized的数据,equals()有可能在操作中出现错误。想象 一个对象x,它的一个整型数据是transient型(不能被serialize成二进制数据流)。然而equals()和hashCode()都有依靠 这个整型数据,那么,这个对象在serialization之前和之后,是否一样?答案是不一样。因为serialization之前的整型数据是有效的 数据,在serialization之后,这个整型数据的值并没有存储下来,再重新由二进制数据流转换成对象后,两者(对象在serialization 之前和之后)的状态已经不同了。这也是要注意的。

知道以上这些能够帮助你:

1. 进行更好的设计和开发。

2. 进行更好的测试案例开发。

3. 在面试过程中让面试者对你的学识渊博感到满意。

java读取codetable_解析Java对象的equals()和hashCode()的使用相关推荐

  1. 解析Java对象的equals()和hashCode()的使用

    解析Java对象的equals()和hashCode()的使用 前言 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个.在多 ...

  2. Java读取和解析Excel数据:基于Apache POI(二)

    Java读取和解析Excel数据:基于Apache POI(二) 假设附录1文章中的test.xls是对员工的考勤记录表.需要根据这张excel表统计员工的加班时间,那么需要重点关注第五列的下班时候的 ...

  3. 如何用java读取并解析geojson文件

    工具:json.simple.wowtools json.simple用于读取json文件,wowtools自动适配地解析geojson格式. 1.引入依赖 代码如下(示例): <depende ...

  4. Java、JS解析JSON对象、JSON数组

    一:三种JSON格式 基本类型 {"student": "张三","age": 18,"sex": true } 数组类 ...

  5. java method field_java_解析Java中的Field类和Method类,Field类 Field类中定义了一些方 - phpStudy...

    解析Java中的Field类和Method类 Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够 ...

  6. java编译_解析 Java 即时编译器原理。

    ↑ 点击上面 "时代Java"关注我们,关注新技术,学习新知识! 一.导读 常见的编译型语言如C++,通常会把代码直接编译成CPU所能理解的机器码来运行.而Java为了实现&quo ...

  7. java读取文件服务器文件,java读取远程服务器文件

    java读取远程服务器文件 内容精选 换一换 已成功登录Java性能分析.待安装Guardian的服务器已开启sshd.待安装Guardian的服务器已安装JRE,JRE版本要求为Huawei JDK ...

  8. java 读取office文件,java读取office文件

    在网上百度,然后自己终结写了这篇文章 package cn.rjxh.utils; import java.io.BufferedReader; import java.io.File; import ...

  9. java 读取word 表格,java读取word表格方法

    首先网上下载poi插件poi-bin-3.9-20121203.zip import java.io.File; import java.io.FileInputStream; import java ...

最新文章

  1. mysql 使用EF6.0CodeFirst
  2. 2008-07-29
  3. Hyper-V 2016 系列教程48 Windows Server Backup 一次性备份操作
  4. java自定义jsp标签_深入浅出javaWeb实战第17讲自定义JSP标签(上)
  5. python如何爬虫股票数据_简单爬虫:东方财富网股票数据爬取(python_017)
  6. mysql导入数据表越来越慢,快速解决mysql导数据时,格式不对、导入慢、丢数据的问题...
  7. python查看dataframe数据类型_python pandas中DataFrame类型数据操作函数的方法
  8. Java 方法、 流(Stream)、文件(File)和IO 总结
  9. 计算机课程设计课程计划书,计算机汇编语言课程设计计划书.doc
  10. 微信php实例代码_php微信公众平台示例代码分析(二)
  11. java 获取发布后的路径问题_Java中的路径问题实例分析
  12. A star 算法 (Python)
  13. 2018linux市场份额数据,2018年7月Windows 10市场份额上涨,Linux仅占1.35%
  14. python关闭函数解释器_深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!...
  15. python抓取网页内容并下载图片
  16. OC中iO操作相关方法
  17. 原画学习步骤,零基础一步步学原画!
  18. 【爬虫学得好,JY进得早】:urllib模块详解
  19. Redis 缓存清理策略
  20. Ureport2小计和合计功能

热门文章

  1. docker 部署java_使用Docker堆栈部署的微服务-WildFly,Java EE和Couchbase
  2. 你为什么要关心equals和hashcode
  3. java的默认值规则_Java 8:默认方法解析规则
  4. 叉叉框架_叉/连接框架
  5. 关于Jakarta EE软件包名称更改的思考
  6. jenkins jboss_与JBoss Fuse,Jenkins和Nexus的持续集成
  7. solr 的maven_使用Maven运行Solr
  8. java和golang性能_Java本质和性能
  9. JavaFX技巧23:节省内存! 属性的阴影场
  10. glassfish5_将Glassfish 3连接到外部ActiveMQ 5代理