欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java重写hashcode的标准

程序员文章站 2024-03-22 17:19:58
...

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