hashCode之二--Java:重写equals()和hashCode()

以下内容总结自《Effective Java》。
1.何时需要重写equals()
当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。
2.设计equals()
[1]使用instanceof操作符检查“实参是否为正确的类型”。
[2]对于类中的每一个“关键域”,检查实参中的域与当前对象中对应的域值。
[2.1]对于非float和double类型的原语类型域,使用==比较;
[2.2]对于对象引用域,递归调用equals方法;
[2.3]对于float域,使用Float.floatToIntBits(afloat)转换为int,再使用==比较;
[2.4]对于double域,使用Double.doubleToLongBits(adouble) 转换为int,再使用==比较;
[2.5]对于数组域,调用Arrays.equals方法。
3.当改写equals()的时候,总是要改写hashCode()
根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode方法,它们仅仅是两个对象。因此,违反了“相等的对象必须具有相等的散列码”。
4.设计hashCode()
[1]把某个非零常数值,例如17,保存在int变量result中;
[2]对于对象中每一个关键域f(指equals方法中考虑的每一个域):
[2.1]boolean型,计算(f ? 0 : 1);
[2.2]byte,char,short型,计算(int);
[2.3]long型,计算(int) (f ^ (f>>>32));
[2.4]float型,计算Float.floatToIntBits(afloat);
[2.5]double型,计算Double.doubleToLongBits(adouble)得到一个long,再执行[2.3];
[2.6]对象引用,递归调用它的hashCode方法;
[2.7]数组域,对其中每个元素调用它的hashCode方法。Arrays.hashCode(...)只会计算一维数组元素的hashCOde,如果是多维数组,那么需要递归进行hashCode的计算,那么就需要使用Arrays.deepHashCode(Object[])方法。
[3]将上面计算得到的散列码保存到int变量c,然后执行 result=37*result+c;
[4]返回result。
为什么每次需要使用乘法去操作result? 
主要是为了使散列值依赖于域的顺序,还是上面的那个例子,Test t = new Test(1, 0)跟Test t2 = new Test(0, 1), t和t2的最终hashCode返回值是不一样的。
为什么是31? 31是个神奇的数字,因为任何数n * 31就可以被JVM优化为 (n << 5) -n,移位和减法的操作效率要比乘法的操作效率高的多。
我们应该先了解java判断两个对象是否相等的规则。
在java的集合中,判断两个对象是否相等的规则是: 
首先,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等 
如果不相等,认为两个对象也不相等 
如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率
如何重写hashCode方法呢?
5.示例
下面的这个类遵循上面的设计原则,重写了类的equals()和hashCode()。
package com.zj.unit;
import java.util.Arrays;
public class Unit {
private short ashort;
private char achar;
private byte abyte;
private boolean abool;
private long along;
private float afloat;
private double adouble;
private Unit aObject;
private int[] ints;
private Unit[] units;
public boolean equals(Object o) {
if (!(o instanceof Unit))
return false;
Unit unit = (Unit) o;
return unit.ashort == ashort
&& unit.achar == achar
&& unit.abyte == abyte
&& unit.abool == abool
&& unit.along == along
&& Float.floatToIntBits(unit.afloat) == Float
.floatToIntBits(afloat)
&& Double.doubleToLongBits(unit.adouble) == Double
.doubleToLongBits(adouble)
&& unit.aObject.equals(aObject)
&& equalsInts(unit.ints)
&& equalsUnits(unit.units);
}
private boolean equalsInts(int[] aints) {
return Arrays.equals(ints, aints);
}
private boolean equalsUnits(Unit[] aUnits) {
return Arrays.equals(units, aUnits);
}
public int hashCode() {
int result = 17;
result = 37 * result + (int) ashort;
result = 37 * result + (int) achar;
result = 37 * result + (int) abyte;
result = 37 * result + (abool ? 0 : 1);
result = 37 * result + (int) (along ^ (along >>> 32));
result = 37 * result + Float.floatToIntBits(afloat);
long tolong = Double.doubleToLongBits(adouble);
result = 37 * result + (int) (tolong ^ (tolong >>> 32));
result = 37 * result + aObject.hashCode();
result = 37 * result + intsHashCode(ints);
result = 37 * result + unitsHashCode(units);
return result;
}
private int intsHashCode(int[] aints) {
int result = 17;
for (int i = 0; i < aints.length; i++)
result = 37 * result + aints[i];
return result;
}
private int unitsHashCode(Unit[] aUnits) {
int result = 17;
for (int i = 0; i < aUnits.length; i++)
result = 37 * result + aUnits[i].hashCode();
return result;
}
}

转载于:https://www.cnblogs.com/duanxz/p/3890046.html

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

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

相关文章

毛绒材质渲染_学室内设计必进,建模渲染那都不是事儿

近年来&#xff0c;室内设计从业人员需求量和薪酬持续增长带来的是室内设计行业的飞速发展&#xff0c;而设计能力也成为“创新与创造”的不可或缺。设计能力是多方面能力的综合体现而室内效果图作为设计成果的最主要表现手段&#xff0c;是最基础也是最重要的技能之一。那么持…

2020年末总结,脚踏实地,一步一个脚印——致敬自己一年的心酸历程

摘要:恰逢官方征文,谨以此篇记录自己一年的心酸历程与前端知识的感悟。 目录 在时代工场的主要工作 我为什么从时代工场离职?

第六章 面向对象(下)

1. 不上机&#xff0c;判断下面程序的输出结果 class X {Y b new Y();X() {System.out.print("X");} } class Y {Y() {System.out.print("Y");} } public class Z extends X {Y y new Y();Z() {System.out.print("Z");}public static void mai…

如何使用Java 8函数式编程生成字母序列

我偶然发现了用户“ mip”一个有趣的堆栈溢出问题 。 问题是&#xff1a; 我正在寻找一种生成字母序列的方法&#xff1a; A, B, C, ..., Z, AA, AB, AC, ..., ZZ.可以很快将其识别为Excel电子表格的标题&#xff0c;正是这样&#xff1a; 到目前为止&#xff0c;没有答案使…

maven 打包指定依赖包_[Maven]-Maven基础-01-基础概念

Maven基础1.基础概念Maven基础概念什么是Maven什么是理想的项目构建&#xff1f;高度自动化&#xff0c;跨平台&#xff0c;可重用的组件&#xff0c;标准化的什么是依赖&#xff1f;为什么要进行依赖管理&#xff1f;自动下载&#xff0c;统一依赖管理有哪些项目信息&#xff…

关于本人在多个技术平台发布文章的声明

摘要:由于博主有经常记录博客的习惯,很多其他平台的运营或者编辑多多少少会找到我,让我在他们的平台更新文章,写这篇文章主要为了陈述事实与避免纠纷。 本博客会长期维护更新,感谢大家的理解与支持。 孙叫兽目前只在CSDN、开源中国、掘金、infoq、腾讯云+技术社区上更新博…

架构之路(八)从CurrentUser说起

CurrentUser&#xff0c;也就是当前用户&#xff0c;这是我们系统中大量使用的一个概念。 确认当前用户 当然&#xff0c;我们利用的是cookie&#xff1a;用户的ID存放在cookie中&#xff0c;服务器端通过cookie中的Id&#xff0c;查找数据库&#xff0c;得到需要的用户信息。 …

手写爬虫框架

前言 参照了Scrapy、Feapder的设计模式&#xff0c;实现的一个轻量级爬虫框架&#xff08;目前约200行代码&#xff09; 源码地址 https://gitee.com/markadc/pader 项目持续更新中…

cmseasy漏洞复现

介绍 提供可视化编辑企业网站管理系统系统、网站模板、以及相关文档资料下载,网站系统完美运 行PHP7环境中。 官方网站: https://www.cmseasy.cn/ cmseasy_7.3.8 任意文件操作漏洞复现 cmseasy_7.6.3.2逻辑漏洞复现 "无需代码&#xff0c;自由拖拽布局&#xff0c;适应…

教你如何看待程序员这个职业的前前后后

现在大家的学历基本提升上来啦&#xff0c;基本搞编程的都是本科或者大专起步&#xff0c;这里仅那本科举例。 好多大学生跟我说是计算机专业&#xff0c;软件工程专业等&#xff0c;啥都学一点&#xff0c;这样真的好&#xff1f; 对于大学生&#xff0c;如果是计算机相关专业…

请领导批阅文件怎么说_刚到公司,应该怎么喊领导,别直接说名字,高情商这样称呼...

刚到公司&#xff0c;应该怎么喊领导&#xff0c;别直接说名字&#xff0c;高情商这样称呼我们都有经历过刚刚从大学毕业出来后&#xff0c;寻求工作的场景。一般来说&#xff0c;我们都是会选择和自己大学所学专业挂钩的职业&#xff0c;在这样的情况下&#xff0c; 我们的选择…

正则表达式的汉字匹配

这里是几个主要非英文语系字符范围 2E80&#xff5e;33FFh&#xff1a;中日韩符号区。收容康熙字典部首、中日韩辅助部首、注音符号、日本假名、韩文音符&#xff0c;中日韩的符号、标点、带圈或带括符文数字、月份&#xff0c;以及日本的假名组合、单位、年号、月份、日期、时…

分屏显示_2021元旦高性价比显示器推荐——便携式显示器选购指南(分屏办公、小尺寸办公必备)...

想要告别小显示器选择困难症&#xff0c;挑选到自己心仪的小显示器&#xff0c;大家看这篇文章就够了&#xff01;显示器是PC的重要组成部分&#xff0c;在应用程序级别具有“场景”属性。显示器的要求因办公&#xff0c;娱乐和学习等不同应用而异。无论应用场景如何&#xff0…

为Jersey 2.19创建共享库以与Weblogic 12.1.3一起使用

Weblogic服务器带有一个共享库&#xff0c;因此您可以部署JAX-RS 2.0应用程序。 但是仅限于Jersey 2.5.1版&#xff0c;更改的说明并不完全清楚或直观 。 我最近加入了Oracle的新团队&#xff0c;我要做的第一件事就是着眼于升级依赖库。 现在我已经与泽西队进行了交谈&#xf…

一键反编译Android包教程

功能介绍 某些时候我们想修改apk包内容&#xff0c;比如汉化某个游戏&#xff0c;这时候就需要修改游戏apk的包内容&#xff0c;并重新签名成安卓手机识别的apk文件&#xff0c;下面详细介绍&#xff0c;文章末尾有一键修改工具。&#xff08;注意&#xff1a;此工具尚未整合修…

发现一个可视化大屏操作神器FBI,你值得一试

FineBI 是帆软软件有限公司推出的一款商业智能(Business Intelligence)产品。 FineBI 自助分析以业务需求为方向,通过便携的数据处理和管控,提供自由的探索分析。 FineBI 定位于自助大数据分析的 BI 工具,能够帮助企业的业务人员和数据分析师,开展以问题导向的探索式…

贝叶斯决策

参考文献&#xff1a;http://wenku.baidu.com/link?urlbCWUt2SDACsX6CXndtF8uEeYRo9r33hDVTaDORFcd8sAWbL4hYqmjDeyn5RfyYZ3VjzbnQvLVrNoBapp617_kmTCCKlDV4K_1E4-nTenauO 1&#xff09;Neyman-Pearson 准则 2&#xff09;最小错误率准则 3&#xff09;贝叶斯风险最小准则 4&a…

使用java发送电子邮件_使用Java发送电子邮件

使用java发送电子邮件我开始使用Java作为简单的“如何发送电子邮件”来撰写这篇文章&#xff0c;但是后来我发现我需要简要解释更多事情。 因此&#xff0c;这是有关使用Java发送电子邮件的所有摘要。 在Java SE平台之外&#xff08;但包含在JavaEE中&#xff09;&#xff0c; …

uniapp去掉右侧滚动条的解决办法?

用 uniapp 开发小程序,内容多的情况下,在微信开发者工具和真机调试下,右侧出现滚动条,有没有办法隐藏滚动条? 参考文档:https://uniapp.dcloud.net.cn/collocation/pages?id=app-plus 解决办法一: 参考文档:https://uniapp.dcloud.net.cn/collocation/pages?id=app-plus…

内网渗透工具CobaltStrike使用教程详解

文章目录 前言一、CobaltStrike本次实验环境 二、CobaltStrike详细使用1.启动CobaltStrike2.客户端连接团队服务端3.配置监听器4.生成木马5.权限提升&#xff0c;命令执行以及内网横线穿透等。6.插件加载7.命令执行等操作8.目标信息总结表&#xff08;自动记忆保存&#xff09…