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

解析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. 在面试过程中让面试者对你的学识渊博感到满意。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jvm体系结构_JVM体系结构:JVM中的执行引擎

jvm体系结构各位读者好! 在JVM系列的上一篇文章中,开发人员了解了虚拟机的ClassLoader和Runtime Data Areas组件。 本教程将帮助开发人员正确理解JVM中的执行引擎 。 1.简介 在继续之前,让我们看一下Java虚拟机及其基本特征。 1.1什么是Jav…

如何才能不改变图片的像素大小,只改变图片的文件大小

如图,有一张这样的图片,我们需要对它进行压缩: 处理前该图片的像素尺寸和文件大小如图所示: 接着我们使用PS打开该图片,如果不想改变尺寸大小,只改变文件大小。点击菜单【文件】->【存储为web和设备所…

java通用编码规范考试_《java编码规范考试题答案》.doc

一、单选题1. 如下关于集合类的描述错误的是 BA. 含有集合意义的属性命名,尽量包含其复数的意义B. 集合中的数据不需要释放,垃圾回收器会自动回收C. 集合必须指定模板类型D. 使用集合类时要设置初始化容量2. 关于线程以下说法错误的有BA. 新起一个线程&a…

Alfred 功能组合键/快捷键

文章目录快捷键如何设置呼出热键参考文章快捷键 快捷键说明Fn在选中的文件或者目录上点击 Fn 键可以触发其额外的操作,可以在【Actions】里面进行配置Command Enter可以进入当前文件所在的文件夹中Space 搜索词查找指定相关的文件,选中后按回车打开此…

vaadin教程_Vaadin教程

vaadin教程1.简介 当您是后端开发人员时,您会听到别人说您无法创建内置HTML的UI页面并且无法在CSS中设置样式而引起的痛苦。 就像成为后端开发人员一样,它具有已知的局限性,即我们可以播放和运行大型生产后端应用程序,但不能创建漂…

c 和java互相验签_C椭圆曲线签名 用java验签

C椭圆曲线签名 用java验签,java应该用什么类,new X509EncodedKeySpec( hex2Bytes(publicKey) ) 一直报错签名:294236F3FEA929A45A3544A40BE7546CCE71DD52B5B488C12C05A440440B21120C3F127FE4B53326DCE1AAE393B36EB1B57C09EF7B3230760F5C493F6…

混合多云架构_使用混合多云每个人都应避免的3个陷阱(第3部分)

混合多云架构每天都在肆意宣传云,但每个人都应避免三个陷阱。 从云,混合云到混合多云,您都被告知这是确保业务数字化未来的一种方式。 您必须做出的这些选择不会排除提高客户体验和敏捷交付这些应用程序的日常工作。 让我们开始一段旅程&am…

MacOS的Automator(自动操作)实用案例详解/自定义程序/自定义服务

文章目录创建新建文本文件的服务创建批量开启多个应用程序的服务创建批量开启多个应用程序的程序创建退出所有程序的服务如何删除/隐藏创建的服务删除服务隐藏服务创建新建文本文件的服务 打开 Automator 后,选择「快速操作」后,点击下方按钮「选取」&a…

用来编译java源文件的工具_基于阿里开源yugong工具类,动态编译Java源文件

适用场景:Java应用满足用户自定义需求场景实例代码:测试用例(DynamicCompileTest)package com.taobao.yugong.common;import java.io.IOException;import java.util.List;import junit.framework.Assert;import org.apache.commons.io.IOUtils;import or…

MacOS 下如何创建文本文件

文章目录通过 MacOS 自带的 Automator 创建自动化服务程序实用 Finder 扩展工具 - New File Menu通过 MacOS 自带的文本编辑程序创建通过 MacOS 自带的 Automator 创建自动化服务程序 欲知此方法请猛戳《MacOS 的 Automator 实用案例详解》 实用 Finder 扩展工具 - New File …

jdk12源代码文件_在JDK 11中启动单文件源代码程序

jdk12源代码文件JEP 330 –启动单文件源代码程序是即将发布的JDK 11(18.9)发行版中令人兴奋的功能之一。 此功能允许直接使用java解释器执行Java源代码。 源代码在内存中编译,然后由解释器执行。 限制是必须在同一文件中定义所有类。 对于刚…

java控制图片移动_多线程控制图片移动

帮忙看下为什么图片没有显示 图片目录在src 下的image 文件夹中package com.thread;import java.awt.EventQueue;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JLabel;public class SleepDemo extends JFrame implements Runnable {private JLa…

Linux 命令之 cut -- 分割字符串,显示或删除指定字段的内容,合并文件内容

文章目录一、命令介绍二、常用选项三、命令示例根据指定的字节范围显示指定文件中的内容指定字段分隔符,显示指定字段的内容显示指定字段的内容根据指定的字符范围显示指定文件中的内容显示指定字段以外的字段的内容以指定的输出分隔符来分割输出内容中的字段合并多…

java 抛异常 jvm_邪恶的Java技巧使JVM忘记检查异常

java 抛异常 jvm我长期以来一直在批评Java中编译器检查异常的机制。 无论您是爱还是恨,都可以肯定一件事:在某些情况下,您不想与他们打交道。 Java中的解决方案是将一个检查后的异常包装在new RuntimeException(e)但这可以提供较长的堆栈跟踪…

java空文本_输出到文本文件,控制台为空-Java

首先,您必须创建一个从OutputStream接口继承的类以实现适配器模式(我不确定是否是adapter)那么您可以使用该类作为波纹管主要PrintStream finalStream;TreeOutputStream tos;PrintStream out;out new PrintStream("logs.txt");tos new TreeOutputStream();tos.add(…

Linux 组合命令/命令组合的符号

在 EX 命令中,竖直线 | 是命令的分割符,它允许用户把多个命令组合在一起执行Shell 命令使用分号 ; 组合命令

混合多云架构_使用混合多云每个人都应避免的3个陷阱(第4部分)

混合多云架构每天都在肆意宣传云,但每个人都应避免三个陷阱。 从云,混合云到混合多云,您都被告知这是确保业务数字化未来的一种方式。 您必须做出的这些选择不会排除提高客户体验和敏捷交付这些应用程序的日常工作。 让我们开始一段旅程&…

Linux 中常见的较为复杂的命令实例

文章目录 命令 find 和命令 grep 联合使用命令 find 和 命令 convert 联合使用命令 find 和命令 rm 联合使用命令 find 和命令 xargs 联合使用命令 sed 和目录 grep 联合使用命令 find 和命令 grep 联合使用 [root@htlwk0001host test]# find . -name "*.txt" -exec…

mysql 触发器 注意事项_MySQL触发器的利弊-使用MySQL触发器时应该注意的事项

在MySQL中,触发器可以在你执行INSERT、UPDATE或DELETE的时候,执行一些特定的操作。在创建触发器时,可以指定是在执行SQL语句之前或是之后执行这些操作。通过触发器,你可以实现一些业务逻辑或一些数据限制,在…

混合多云架构_使用混合多云每个人都应避免的3个陷阱(第2部分)

混合多云架构如果您已经完全控制了本地数据中心,但又不能停止利用和支付过多的资源,那么如何期望防止这些成本转嫁到您的云策略中呢? 每天都在肆意宣传云,但每个人都应避免三个陷阱。 从云,混合云到混合多云&#xff0…