http://my.oschina.net/chihz/blog/56256

Google首席Java架构师Joshua Bloch在他的著作《Effective Java》中提出了一种简单通用的hashCode算法
1. 初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;
2. 选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算:
(1) 如果是boolean值,则计算f ? 1:0
(2) 如果是byte\char\short\int,则计算(int)f
(3) 如果是long值,则计算(int)(f ^ (f >>> 32))
(4) 如果是float值,则计算Float.floatToIntBits(f)
(5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int
(6) 如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。  否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode 值为0
(7) 如果是数组,那么需要为每个元素当做单独的域来处理。如果你使用的是1.5及以上版本的JDK,那么没必要自己去    重新遍历一遍数组,java.util.Arrays.hashCode方法包含了8种基本类型数组和引用数组的hashCode计算,算法同上,
java.util.Arrays.hashCode(long[])的具体实现:
public static int hashCode(long a[]) {if (a == null)return 0;int result = 1;for (long element : a) {int elementHash = (int)(element ^ (element >>> 32));result = 31 * result + elementHash;}return result;
}
Arrays.hashCode(...)只会计算一维数组元素的hashCOde,如果是多维数组,那么需要递归进行hashCode的计算,那么就需要使用Arrays.deepHashCode(Object[])方法。

3. 最后,要如同上面的代码,把每个域的散列码合并到result当中:result = 31 * result + elementHash;

4. 测试,hashCode方法是否符合文章开头说的基本原则,这些基本原则虽然不能保证性能,但是可以保证不出错。
2. 为什么每次需要使用乘法去操作result? 主要是为了使散列值依赖于域的顺序,还是上面的那个例子,Test t = new Test(1, 0)跟Test t2 = new Test(0, 1), t和t2的最终hashCode返回值是不一样的。
3. 为什么是31? 31是个神奇的数字,因为任何数n * 31就可以被JVM优化为 (n << 5) -n,移位和减法的操作效率要比乘法的操作效率高的多。

通用的Java hashCode重写方案相关推荐

  1. 在Java里重写equals和hashCode要注意什么问题

    问题:在Java里重写equals和hashCode要注意什么问题 重写equals和hashCode有哪些问题或者陷阱需要注意? 回答一 理论(对于语言律师或比较倾向于数学的人): equals() ...

  2. Java中重写equals()方法时注意点

    Java中重写equals()方法时注意点 一直说,重写一个对象的equals()方法时我们必须重写HashCode()方法,但是如果我们不重写呢?会有什么影响呢? 首先看一下,什么情况下我们需要重写 ...

  3. tsql语句中的t是什么_TSQL中的Java HashCode

    tsql语句中的t是什么 The Java HashCode method is used to determine uniqueness or similarity of strings. Whil ...

  4. Java hashCode() 和 equals()的若干问题解答

    参考文章:https://www.cnblogs.com/skywang12345/p/3324958.html 本文的内容主要解决下面几个问题: 1 equals() 的作用是什么? 2 equal ...

  5. Java 方法重写与重载的区别 示例 重载多数相加求和 重写toString()和equals()

    Java 方法重写与重载的区别 重载:在同一个类中,当方法名相同,形参列表不同的时候 多个方法构成了重载 重写:在不同的类中,子类对父类提供的方法不满意的时候,要对父类的方法进行重写. 名称\属性 E ...

  6. Java Cache 缓存方案详解及代码-Ehcache

    一.Spring缓存概念 Spring从3.1开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManage ...

  7. 一套通用的VUE后台管理系统方案(vite+Vue3+ts)

    通用后台管理系统整体架构方案(Vue) 项目创建,脚手架的选择(vite or vue-cli) vue-cli基于webpack封装,生态非常强大,可配置性也非常高,几乎能够满足前端工程化的所有要求 ...

  8. 基于Java微服务方案的商品秒杀系统

    前言 项目是基于Java微服务方案的商品秒杀系统.是前后端分离的项目,前端用React,后端为Java的微服务架构.项目本身用于学习,在一些地方还不够成熟,欢迎各位多多交流. 客户端前端服务器 后台系 ...

  9. java 静态方法重写_Java 类中可以覆盖静态方法吗?

    Java技术栈 www.javastack.cn 打开网站看更多优质文章 Java 类中可以覆盖静态方法吗? 不,你不能在Java中覆盖静态方法,但在子类中声明一个完全相同的方法不是编译时错误,这称为 ...

最新文章

  1. sendmail邮件服务器支持账户名大小写
  2. iptables规则备份和恢复,任务计划chkconfig工具systemd管理服务
  3. bzoj 4945: [Noi2017]游戏
  4. MySQL分页查询语句
  5. vue使用better-scroll实现下拉刷新、上拉加载
  6. VMware中ubuntu虚拟机与windows的端口映射,共享一个IP地址
  7. 将PDF转为TXT文本格式提取中文
  8. 量子计算云平台“中国版”启动 量子信息革命正在加速到来
  9. linux脚本 exe,Powershell下载并运行exe文件
  10. UE5 预览版载具模板工程车不能移动的问题
  11. Java设计模式——行为型模式之观察者模式
  12. 金融系列-会计基础知识
  13. kotlin框架Anko的使用及常用的项目配置
  14. 联通云OSS上传文件
  15. 00 Linux到底是什么?
  16. 微信小程序的脚本就是c语言,新手尝试编写微信小程序(2)——我的第一个微信小程序...
  17. android6.0原生壁纸,惊呆了!安卓6.0壁纸竟然是这样得来的
  18. 【元胞自动机】基于元胞自动机模拟双通道人群疏散含Matlab源码
  19. ubuntu上安装视频插件
  20. linux系统FW升降级步骤,[Fw]初探linux中断系统(2)

热门文章

  1. Java中byte[]与十六进制之间的转化
  2. 额外篇 | ggplot (下)
  3. 降低百倍时间步,精度媲美传统神经网络:上交等机构提出ANN-SNN转换框架
  4. 北京内推 | 微软亚洲研究院DKI组王露研究员招聘强化学习方向研究实习生
  5. AI安检:北航提出安检场景下的危险品检测基准和去遮挡注意力模块
  6. ICITR 2021 | 排序算法中的用户公平性、item公平性和多样性
  7. ICLR 2021 | 使用CVAE学习干扰集,增强OOD以及对抗防御的能力
  8. CVPR 2021 | 澳洲国立大学提出基于模型的图像风格迁移
  9. Java第三章 类和对象3.1+3.2
  10. C++结构体多级排序的三种方法