1. 把某个非零常数值,比如说17,保存在一个叫result的int类型的变量中。

2.对于对象中每一个关键域f(值equals方法中考虑的每一个域),完成以下步骤:

a.为该域计算int类型的散列吗c:

i. 如果该域是boolean类型,则计算

[java] view plain copy
f?0:1

ii. 如果该域是byte、char、short或者int类型,则计算
[java] view plain copy
(int)f

iii.如果该域是long类型,则计算
[java] view plain copy
(int)(f ^ (f >>> 32))

iv. 如果该域是double类型,则计算
[java] view plain copy
Double.doubleToLongBits(f)

得到一个long类型的值,然后按照2.a.iii,对该long型值计算散列值。

vi. 如果该域是一个对象引用,并且该类的equals方法通过递归调用equals的方式来比较这个域,则同样对这个域递归调用hashCode,如果要求一个更为复杂的比较,则为这个域计算一个“规范表示(canonical representation)”,然后针对这个范式调用hashCode。如果这个域为null,则返回0(或者是某个常数,但习惯上使用0)。

vii. 如果该域是一个数组,则把每一个元素当做单独的域处理。也就是说,递归地应用上诉规则,对每一个重要的元素计算散列值,然后根据2.b的方法把这些散列值组合起来。

b.按照下面的公式,把步骤a得到的散列值组合到result中:

[java] view plain copy
result = 37 * result + c;

3.返回result
4.写完了hashCode后,问自己相等的实例具有相同的hashCode么?假如不是,找出原因并修正。

在散列码的计算过程中,把冗余域排除在计算之外是可以接受的。换句话说,如果一个域的值可以根据其他域值计算出来,则把这样的域排除在外是可以接受的。

举例,假如一个类PhoneNumber有三个关键域:areaCode,exchange,extension,都是short类型,则hashCode的计算过程为:

[java] view plain copy
@Override
public int hashCode(){
int result = 17;
result = result * 37 + areaCode;
result = result * 37 + exchange;
result = result * 37 + extension;
return result;
}
如果一个类是可变的,并且计算散列码的代价也比较大,那么你应该考虑把散列码缓存到对象的内部,而不是每次请求的时候都计算散列值。如果你觉得这种类型的大都数值会被用作散列键,那么你应该在实例被创建的时候计算散列值,否则,你可以选择“延迟初始化”散列码,一直到hashCode第一次调用才开始计算。
假如PhoneNumber这样处理,那么代码为:

[java] view plain copy
//延迟初始化
private volatile int hashCode = 0;

@Override
public int hashCode(){
if(hashCode == 0){
int result = 17;
result = result * 37 + areaCode;
result = result * 37 + exchange;
result = result * 37 + extension;
hashCode = result;
}
return hashCode;
}

计算hashCode的常见方法相关推荐

  1. 电子计算机机房折旧提几年,IDC设备资产运营中四种“折旧率计算”的常见方法...

    原标题:IDC设备资产运营中四种"折旧率计算"的常见方法 数据中心基础设施设备管理中设备的折旧是固定资产的折旧.该基础设施设备或者IT设备在长期使用后仍可保持其原始物理形态,但由于 ...

  2. 可解释机器学习发展和常见方法!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 来源:新智元,编辑:数据派THU 本文约2000字,建议阅读5分钟 本文 ...

  3. 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写 hashcode 和 equals 方法?...

    1. 通过Hash算法来了解HashMap对象的高效性 2. 为什么要重写equals和hashCode方法 3. 对面试问题的说明 <Java 2019 超神之路> <Dubbo ...

  4. 灰度图像阈值化分割常见方法总结及VC实现

    灰度图像阈值化分割常见方法总结及VC实现 分类: 图像处理 OpenCV2011-11-11 23:20 609人阅读 评论(11) 收藏 举报 在图像处理领域,二值图像运算量小,并且能够体现图像的关 ...

  5. 为什么要重写 hashcode 和 equals 方法?

    我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...

  6. 为什么使用HashMap需要重写hashcode和equals方法_为什么要重写hashcode和equals方法?你能说清楚了吗...

    我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分,有 ...

  7. 一文读懂领域迁移与领域适应的常见方法

    ©PaperWeekly 原创 · 作者|Chen 单位|追一科技AI Lab研究员 研究方向|领域迁移.领域适应 领域迁移问题的背景及描述 在使用机器学习.人工智能中的技术手段解决实际问题的时候,常 ...

  8. HashCode和equal方法

    equals()反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. 而hashCode()是对象或变量通过哈希算法计算出的哈希值. 之所以有hashCode方 ...

  9. 继承的概念和实现 、 super关键字 、 Object常见方法、抽象类、接口、模板方法模式、成员内部类、匿名内部类

    这篇博客将会涉及到: 继承的概念和实现 super关键字 方法重写-Override Object常见方法 继承的概念: 生活中,继承的概念随处可见,继承需要符合的关系:is-a:父类更通用.子类更特 ...

  10. java 异常继承体系_1、异常概述和继承体系 2、原因及处理方式 3、运行时异常 4、重写异常处理 5、Throwable类常见方法 6、自定义异常...

    01异常的概述 * A: 异常的概述 * a:什么是异常 * Java代码在运行时期发生的问题就是异常. * b:异常类 * 在Java中,把异常信息封装成了一个类. * 当出现了问题时,就会创建异常 ...

最新文章

  1. Troubleshooting OpenStack Bug- 每天5分钟玩转 OpenStack(162)
  2. 【算法设计与分析】07 算法的数学基础
  3. java中if结构用图表示_Java if语句结构和指令流水线
  4. Hive启动的三种方式
  5. Mapx中的图元移动
  6. iOS开发日记56-详解UIImage
  7. python彩票号码生成器
  8. 微信网页开发(2)--使用微信开发者工具
  9. matlab 指定ccs编译器,在CCS5.5中导入CCS3.3工程——指定编译器和修改prj文件
  10. 苹果手机需要清理垃圾吗?
  11. 0504-android-云知声sdk使用
  12. 超实用!教你用 Python 获取并下载美股数据
  13. ExoPlayer在开启循环播放时 统计播放次数和索引
  14. 微信小程序引用外部文件找不到文件报错问题
  15. 安卓和iOS的兼容性问题: 键盘弹起时,固定在底部的按钮是否被弹到键盘上方
  16. css+svg实现的定宽高比
  17. Python:绘制数学图形(2)
  18. 7、JSON数据和Java对象的相互转换(客户端和服务器对象数据通讯用)
  19. 树莓派3b+安装ubuntu 16.04+ROS kinetic过程详解及踩坑总结
  20. C# Bitmap转Mat类型

热门文章

  1. Ibatis 动态查询
  2. 每日学习笔记(17)
  3. html position属性作用,CSS学习之浅谈position属性
  4. 从物理页面的争抢看linux内核内存管理
  5. 如何查看当前音频的输出路径
  6. Linux 文件系统(三)---dup和fork函数执行后的文件情况
  7. 距离之和最小 V3 51Nod - 1110(带权中位数或者爆搜)
  8. 数论基础——欧拉函数(一)(模板)
  9. spark rdd详解一(rdd入门)
  10. 【解题报告】图论基础练习(一)