重写equals和hashCode的原则规范

2024-09-05 22:58

本文主要是介绍重写equals和hashCode的原则规范,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 当符合以下条件时不需要重写equals方法:

    1.     一个类的每一个实例本质上都是唯一的。

    2.     不关心一个类是否提供了“逻辑相等”的测试功能

    3.     超类已经改写了equals方法,并且从超类继承过来的行为对于子类也是合适的。

    4.     一个类时私有的或者是package私有的,并且可以确定它的equals方法永远不会被调用。(这种情况下最好将equals方法改写成以下方式:

        public boolean equals(Object obj){

            throws new UnsupportOperationException();
        }

    只有当一个类有自己特定的“逻辑相等”概念,而且超类也没有改写equals以实现期望的行为,我们需要改写equals方法。通常适用于“值类”。

    在改写equals方法时,也要遵守他们的通用约定(equals方法实现了等价关系):

        1.     自反性:x.equals(x) = true;

        2.     对称性:如果有x.equals(y) = true,那么一定有y.equals(x) = true;

        3.     传递性:对任意的x,y,z。如果有x.equals(y) = y.equals(z) = true,那么一定有x.equals(z)= true;

        4.     一致性:无论多少次调用,x.equals(y)总会返回相同的结果。

        5.     非空性(暂定):所有的对象都必须!=null;

 上面的只是理论性的说法,更加具体的做法如下:

        1.     使用==操作符检查“实参是否为指向对象的一个引用”,如果是则返回true;

        2.     使用instanceof操作符检查“实参是否为正确的类型”,如果不是,则返回false;

        3.     将实参装换为正确的类型;

        4.     对于该类中的每一个关键域,检查实参中的域与当前对象中对应的域是否匹配。如果所有测试都成功,则返回true,否则返回false。

        5.     方法完成之后,确定equals方法的对称性,传递性,一致性。

 一些忠告:
        1.改写equals方法的时候,必须改写hashCode方法;

        2.不要把equals声明中的Object对象替换为其他类型;

    改写的形式必须为:public boolean equals(Object obj){...code segment...}

改写equals时总要改写hashCode

              hashCode的通用约定如下:

        1.     只要对象equals方法涉及到的关键域内容不改变,那么这个对象的hashCode总是返回相同的整数。(如果关键域内容改变,则hashCode返回的整数就可以改变)。

        2.     如果两个对象的equals(Object obj)方法时相等的,那么调用这两个对象中的任意一个对象的hashCode方法必须产生相同的整数结果。如果两个对象equals方法不同,那么必定返回不同的hashCode整数结果。(简而言之:相等的对象必须有相等的散列码即hashCode);

    一个好的hashCode方法趋向于“为不相等的对象产生不相等的散列码”理想情况下的散列函数应该把一个集合中不相等的实例均匀分布到所有可能的散列值上。下面给出一种参考方法:

        1.     把某个非零常数值保存在一个叫做result的int类型的变量中

        2.     为该对象中的每一个关键域f计算int类型的散列码。

            a)      为该域计算int类型的散列码c:

                i.如果域是Boolean类型,计算:(f?0:1)

                ii.如果是byte,char,short,int类型,计算:(int)f

                iii.如果是long类型,计算:(int)(f^(f>>32))

                iv.如果是float类型,计算:Float.floatToIntBits(f)

                v.如果是double类型,计算Double.doubleToLongBits(f)得到long类型的值,在按照long值对待,继续进一步计算

                vi.如果是对象引用,递归调用hashCode方法计算,如果遇到为null的关键域,则返回0

                vii.如果是数组,将每一个元素都当做单独的域来计算,递归应用上述规则 

            b)      按照下面公式,将a得到的散列码c组合到result中

                result = 37*result + c;

        3.     返回result

        4.     写完之后,检查hashCode方法是否相等的实例具有相等的散列码,并找出错误原因。

这篇关于重写equals和hashCode的原则规范的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140299

相关文章

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

JavaEE7 Servlet 3.1(JSR 340)规范中文版

http://www.iteye.com/news/27727-jinnianshilongnian     Jave EE 7中的部分规范已正式获得批准通过,其中包括JSR340 Java Servlet 3.1规范,去年翻译了该规范,在此分享出来,希望对某些朋友有所帮助,不足之处请指正。   点击直接下载    在线版目录   Servlet3.1规范翻译

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由

【C/C++】变量命名规范

在 C++ 中,为 bool 类型的变量命名时,通常遵循以下命名规范,以确保代码的可读性和一致性: 表示状态或条件: 使用 is 前缀表示某个状态或条件,例如 isReady、isValid。使用 has 前缀表示是否拥有某个属性,例如 hasData、hasError。使用 can 前缀表示是否具备某种能力,例如 canExecute、canRead。使用 should 前缀表示是否应该执行

Ext重写手法

常用的几种方式:1、Ext.apply()和Ext.applyIf()2、Ext.override()3、想做某个类大的修改,可以把该类单独从源码中拿出来,直接修改,然后引用时先应用ext-all.js,再引用从源码中拿出修改的那个类4、obj.prototype.method=function(){}

水处理过滤器运行特性及选择原则浅谈

过滤属于流体的净化过程中不可缺的处理环节,主要用于去除流体中的颗粒物或其他悬浮物。水处理过滤器的原理是利用有孔介质,从流体中去除污染物,使流体达到所需的洁净度水平。         水处理过滤器的滤壁是有一定厚度的,也就是说过滤器材具有深度,以“弯曲通 道”的形式对去除污染物起到了辅助作用。过滤器是除去液体中少量固体颗粒的设备,当流体进入置有一定规格滤网的滤筒后,其杂质被阻挡,而

二、Java之关键字与命名规范

Java之关键字与命名规范 零基础学Java什么是关键字命名规范的重要性 零基础学Java Java学习交流 : V:study_51ctofx 什么是关键字 关键字:含有特殊意义,编译器解析成特定的含义; 比如 private、int、void、class、enum 等等, 这些关键字都不能用作变量、方法名、类名等. //错误,static 是关键字 不能用作变量名

[mysql]SQL语言的规则和规范

规则 是什么呢,规则就是我们最基本,每时每刻都要遵守的比如人行道靠右,不能逆行, 规范 呢就是锦上添花,如果你不这么做,是不那么道德,不那么好的,就像小学生见到老师要问好,不问好可以吗,当然也是可以的,但是这样就不那么礼貌了。但是也不会开除你, 规范是建议。规则: USE dbtest2 SELECT * FROM emp 我们之前使用cmd操作的时候,是不是必须要先选择一个数据