Java为何重写equals方法得重写hashCode方法
由于在调用equals方法去比较两个对象的时候,会做两个操作,使用==号去比较两个对象的内存地址,如果相同,就返回true;否则继续去比较字符串的值,如果两个字符串的值完全相等,同样返回true。
equals和hashCode有什么区别?
首先Java里的任何一个对象都有一个native的hashCode()方法,其次这个方法在散列集合中会用到,比如hashTable , hashMap这些集合类,当往这些集合类中添加元素的时候,需要判断元素是否存在。如果直接使用equals的话,效率太低,故一般直接使用对象的hashCode的值进行取模以后再运算,如果这个table里面没有这个对象的hashCode的对应的值,那么就可以把这个对象直接存进去,不用再进行任何比较。而如果存在的话,就需要它的equals方法与新的元素进行比较,相同的话就直接覆盖,不相同就散列到其他的地址,所以这里面又存在一个冲突解决的问题,hashCode的值是默认JVM使用随机数生成的,两个不同的对象可能生成的hashCode会相同,这种情况在hash表中所体现的就是hash冲突,通常会使用链表或者线性探测的方法去解决这个冲突,但如果两个完全相同的对象,即内存地址指向同一个,那么他们的hashcode一定是相同的。
所以在理论情况下,如果x.equals(y) == true 。但如果没有重写equals方法,那么这两个堆成的内存地址一定是同一个,意味着hashCode一定相等,但我们如果只重写了equals方法,看就有可能导致,hashCode不相同,一旦出现这个情况,就会导致这个类无法和所有的集合类一起工作,所以在实际开发过程中约定俗成了一条规则,重写equals方法的同时,也需要重写hashCode方法。
所以综上所述:如果只重写equals方法,不重写hashCode方法,就有可能导致a.equals(b)这个表达式成立,但hashCode却不同。这个只重写了equals方法的对象在使用散列集合进行存储的时候就会出现问题。因为散列集合是使用hashCode来计算key的位置,如果存储两个完全相同的对象,但是却有不同的hashCode,就会导致这两个对象存储在hash表的不同位置,当我们想要去根据这个对象去获取数据的时候就会出现一个悖论,一个完全相同的对象会出现在hash表的两个位置,就会破坏大家约定俗成的规则。使我们在程序的编写上出现一些不可预料的错误。
还没有评论,来说两句吧...