Java重写hashcode的标准
hashCode是指在hash maps中使用的哈希码,一旦equals()方法被重写,则hashCode()方法也必须被重写。
当equals方法中涉及的参数没有改变时,hashCode应保持不变。
如果根据equals方法,两个对象是相等的,那么这两个对象的hashCode应该一样。
两个对象如果不相等,hashCode不强制要求不一样,但是如果能保证不一样,对哈希的效率会比较有帮助最重要的是第二点,相等的对象必须有相同的hashCode,由于默认的hashCode方法针对每一个对象返回一个固定的随机值(有的实现是根据对象地址返回值,相当于每一个对象对应一个固定的随机值),所以当我们使用equals方法的同时,必须override(重写)hashCode方法,以满足这一点。
如何计算hashCode
生成一个int类型的变量result,并且初始化一个值,比如17
对类中每一个重要字段,也就是影响对象的值的字段,也就是equals方法里有比较的字段,进行以下操作:a. 计算这个字段的值filedHashValueb. 执行 result = 31 * result + filedHashValue; 更新结果而要如和计算这个字段的值filedHashValue值呢,根据字段类型分为三种情况,一种是基础数据(比如int,boolean,),一种是对象,还有一种是数组。
如何计算每个重要字段的值
如果字段是基础数据,假设数值为f,根据类型
boolean,true返回1,false返回0
byte, char, short, int返回对应的int值
long,返回f^(f>>>32)
float,返回Float.floatToIntBits(f)
double,执行Double.doubleToLongBits(f)转为long,再返回compute(int)(f^(f>>>32))
如果字段是对象,如果是null,返回0,否则根据上述【如何计算hashCode】中所述步骤1和2,计算这个对象的hashCode,作为这个字段的值。实际上是一个递归的过程。
而如果字段是数组,则对每一个元素进行计算,得到filedHashValue,并执行result = 31 * result + filedHashValue;
代码示例:
TantanitReaderPhone的哈希值计算
那么我们让hashCode()每次都返回一个固定的数,比如41,10可以么?
比如可以这么写:
@Override
public int hashCode() {
return 10;
}
如果这样的话,HashMap, HashSet等集合类就失去了其 "哈希的意义".用<Effective Java>中的话来说就是,哈希表退化成了链表.如果hashCode()每次都返回相同的数,那么所有的对象都会被放到同一个bucket中,每次执行查找操作都会遍历链表,这样就完全失去了哈希的作用.所以我们最好还是提供一个健壮的hashCode()为妙.上一篇: 框架问题汇总 博客分类: 问题汇总
推荐阅读
-
Java重写hashcode的标准
-
Java中的hashCode 真的是地址吗?
-
Java重写类的HashCode
-
最近正在重写我自己的数据库框架 博客分类: Java 框架SQLExcelJDBC
-
最近正在重写我自己的数据库框架 博客分类: Java 框架SQLExcelJDBC
-
(转)hashCode与equals的区别与联系 博客分类: java
-
java中的hashCode()方法
-
Java基础学习菜鸟入门第十二天——Java面向对象(六)方法的重写
-
Java重写(Override)与重载(Overload)的那些事儿
-
Java中方法的重载(overload)与重写/覆写(override)