⾯试官可能会问你:“你重写过hashcode
和equals
么,为什么集合里的对象重写equals
时必须重写hashCode
⽅法?”
1) hashCode()
介绍:
hashCode()
的作⽤是获取哈希码,也称为散列码;它实际上是返回⼀个int
整数。这个哈希码的作⽤是确定该对象在哈希表中的索引位置。hashCode()
定义在 JDK 的Object
类中,这就意味着 Java 中的任何类都包含有hashCode()
函数。另外需要注意的是:Object
的hashcode
⽅法是本地⽅法,也就是⽤ 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()的若⼲问题解答
留言