第九条:覆盖equals方法时总要覆盖hashCode方法
Object类的hashCode方法:
public native int hashCode(); 是一个本地方法。
其中这个方法的主要注释如下:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method
must consistently return the same integer, provided no information used in equals comparisons on the object is modified.
在一次应用程序执行期间,只要对象的equals方法没有改变,那么对于同一个对象无论调用多少次hashCode方法,都应该返回同一个整数。
This integer need not remain consistent from one execution of an application to another execution of the same application.
在应用程序的多次执行时,调用hashCode方法,每次执行的返回整数可以不一样 。
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
如果两个对象根据equals方法返回的结果是true,即这两个对象是逻辑相等的,那么这两个对象的hashCode方法应该返回同一个整数。
It is not required that if two objects are unequal according to the {@link java.lang.Object#equals(java.lang.Object)} method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
如果两个对象根据equals方法返回的结果是false,即这两个对象不是逻辑相等的,那么这两个对象的hashCode方法可以返回同一个整数,也可以返回不同的整数,
但是,程序员应该认识到对于逻辑不相等的两个对象,它们的hashCode方法返回不同的整数,有可能提高散列表的性能。
在每个覆盖了equals方法的类中,必须覆盖hashCode方法,那么就会违反上面的hashCode的通用约定,这样导致该类无法结合所有基于散列的集合一起正常工作,
这样的集合包括HashMap,HashSet,Hashtable。
Object类的hashCode方法 ,为每个不同的实例对象返回不同的整数,如果我们覆盖了equals方法,而继承了hashCode方法,那么就算是两个逻辑相等的对象,对于hashCode方法来说,也是两个不同的实例对象,也返回的是不同的整数。
如何写一个好的hashCode方法:
自定义散列函数 ,产生的散列值,使得逻辑相同的对象有相同的散列值(放入同一个桶中),逻辑不同的对象有不同的散列值(放入不同的桶中)。
结合equals方法的关键域,有如下步骤:
1.把一个非零的常数值,如17,保存在一个名叫result的int变量中;
2.对于equals方法中的关键域产生int类型散列值:
boolean类型的域(如名叫f) 计算(f?1:0)
byte,char,short,int类型的域 计算 (int)f
long类型的域 计算 (int)(f^(f>>>32))
float类型的域 计算 Float.floatToIntBits(f)
double类型的域 计算 Double.doubleToLongBits(f)
引用类型的域 使用 引用类型的hashCode方法得到的散列值
数组类型的域 把数组中的每个元素当成一个关键域,计算出散列值。
3.对于每一个关键域计算出来的散列值 (如名叫c)
result = result * 31 + c;
最后放回这个result整数 就是计算出来的当前调用hashCode方法得到的散列值。
注意不要试图从散列值的计算过程中排除一个关键域来提高散列值计算的性能。
关于散列表:
相同散列值的对象被放入同一个桶中,这样寻找一个对象时,先算出这个对象的散列值,就知道到哪个桶中去找这个对象了 ,提高了查找性能。
第九条:覆盖equals方法时总要覆盖hashCode方法的更多相关文章
- 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法
1.背景知识 本文代码基于jdk1.8分析,<Java编程思想>中有如下描述: 另外再看下Object.java对hashCode()方法的说明: /** * Returns a hash ...
- 覆盖equals的时候总要覆盖hashCode
import java.util.HashMap; public class Student { private String name ; private String id; public Stu ...
- 半夜思考, 为什么建议重写 equals() 方法时, 也要重写 hashCode() 方法
我说的半夜, 并不是真正的半夜, 指的是在我一个人的时候, 我会去思考一些奇怪的问题. 要理解 hashCode() 需要理解下面三个点: hash契约 哈希冲突 哈希可变 第一点: hash 契约指 ...
- 覆盖equals时总要覆盖hashCode
本文涉及到的概念 1.为什么重载equals方法时,要重载hashCode函数;没有重载hashCode带来的问题 2.一个对象hashCode的生成规则 1.为什么重载equals方法时 ...
- JAVA中重写equals()方法的同时要重写hashcode()方法
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...
- Item 9 覆盖equals时总要覆盖hashCode
为什么覆盖equals时,总要覆盖hashCode? 原因是,根据Object规范: 如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCod ...
- 第9条:覆盖equals时总要覆盖hashCode
在每个覆盖equals方法的类中,也必须覆盖hashCode方法.否则,会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,包括HashMap,Hash ...
- Effective Java —— 覆盖equals时总要覆盖hashCode
本文参考 本篇文章参考自<Effective Java>第三版第十一条"Always override hashCode when you override equals&quo ...
- why在重写equals时还必须重写hashcode方法
首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anO ...
随机推荐
- 【CJOJ2316】【模板】可持久化线段树
题面 Description 这是一道非常直白的可持久化线段树的练习题,目的并不是虐人,而是指导你入门可持久化数据结构. 线段树有个非常经典的应用是处理RMQ问题,即区间最大/最小值询问问题.现在我们 ...
- [BZOJ2467] [中山市选2010] 生成树 (排列组合)
Description 有一种图形叫做五角形圈.一个五角形圈的中心有1个由n个顶点和n条边组成的圈.在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形.这些五角形只在五角 ...
- [CodeVS2370] 小机房的树 (LCA, 树链剖分, LCT)
Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花 ...
- 纯css实现图片的灯光照射效果,高逼格图片展示
先不说技术,看实现的效果, 与原图(左图)相比,‘灯光’ 照射(右图)下的小姐姐是不是更有魅力了!! 那么下面就说说大家关心的技术实现过程. 其实这是我在学习css属性 mix-blend-mode ...
- 8Manage:聚焦研发企业利器——研发项目管理
[导读]研发是企业保持核心竞争力的基石.那么对于研发企业来说,如何计划研发项目目标.保障项目的稳定运行,如何分配人才.资源,把控项目成本呢?这些一系列问题摆在管理者面前!引入8Manage研发项目管理 ...
- Spring Boot初探之restful服务发布
一.背景 Spring boot是集服务发布.数据库管理.日志管理等于一身的服务开发框架:是微服务开发的全能小帮手.这章讲述一下如何使用spring boot发布restful服务接口. 二.搭建基础 ...
- webstorm提交版本时,忽略特定文件
项目提交时,部分本地配置文件,不需要提交,这时候需要在整个版本控制中忽略掉文件的提交. 操作如下: File -> Settings -> Version Control -> Ig ...
- C++学习-9
友元主要用于访问私有变量,友元函数跟所在位置的权限没有任何关系friend+函数声明 友元类通常设计为一种对数据操作或类之间传递消息的辅助类(注意一下顺序) Explicit就是要求严格的匹配,不允许 ...
- java--Object类接受任意引用数据类型对象
java学习进展到类,首先就对万类之父Object类进行举例练习,这里我是对一维数组和接口用Object接受数组和接口. package test1; public class enum1 { pub ...
- OpenStack Paste.ini详解(二)
接着OpenStack Paste.ini详解(一),接下来就分析request被paste.ini处理的流程 WSGI server接收到URL形式的request时,这些request首先会被Pa ...