⾯试官可能会问你:“你重写过hashcodeequals么,为什么集合里的对象重写equals时必须重写hashCode⽅法?”

1) hashCode()介绍:
hashCode()的作⽤是获取哈希码,也称为散列码;它实际上是返回⼀个int整数。这个哈希码的作⽤是确定该对象在哈希表中的索引位置。hashCode()定义在 JDK 的Object类中,这就意味着 Java 中的任何类都包含有hashCode()函数。另外需要注意的是:Objecthashcode⽅法是本地⽅法,也就是⽤ c 语⾔或 c++ 实现的,该⽅法通常⽤来将对象的内存地址转换为整数之后返回。

public native int hashCode();

散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利⽤到了散列码!(可以快速找到所需要的对象)

2) 为什么要有hashCode

我们以“HashSet如何检查重复”为例⼦来说明为什么要有hashCode
当你把对象加⼊HashSet时,HashSet会先计算对象的hashcode值来判断对象加⼊的位置,同时也会与其他已经加⼊的对象的hashcode值作⽐较,如果没有相符的hashcode,`HashSet
会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调⽤equals()⽅法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加⼊操作成功。如果不同的话,就会重新散列到其他位置。这样我们就⼤⼤减少了equals的次数,相应就⼤⼤提⾼了执⾏速度。

3) 为什么集合里的对象重写equals时必须重写hashCode⽅法?

如果两个对象相等,则hashcode⼀定也是相同的。两个对象相等,对两个对象分别调⽤equals⽅法都返回true。但是,两个对象有相同的hashcode值,它们也不⼀定是相等的 。因此,equals⽅法被覆盖过,则hashCode⽅法也必须被覆盖。

hashCode()的默认⾏为是对堆上的对象产⽣独特值。如果没有重写hashCode(),则该类的两个对象⽆论如何都不会相等(即使这两个对象指向相同的数据)

4) 为什么两个对象有相同的hashcode值,它们也不⼀定是相等的?

因为hashCode()所使⽤的杂凑算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的hashCode
我们刚刚也提到了HashSet,如果HashSet在对⽐的时候,同样的hashcode有多个对象,它会使⽤equals()来判断是否真的相同。也就是说hashcode只是⽤来减少查找成本。

更多关于hashcode()equals()的内容可以查看:Java hashCode() 和 equals()的若⼲问题解答

最后修改日期: 2021年11月20日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。