黑马程序员技术交流社区

标题: 为什么当覆写了equals()方法之后,必须也覆写hashCode()方法 [打印本页]

作者: ┣┫流枫    时间: 2014-8-8 10:33
标题: 为什么当覆写了equals()方法之后,必须也覆写hashCode()方法
本帖最后由 ┣┫流枫 于 2014-8-8 13:41 编辑

为什么当覆了equals()方法之后,必须也覆写hashCode()方法
求大神解释。

作者: 南柯一梦    时间: 2014-8-8 10:41
假如一个类要创建很多对象,而这些对象要存储集合不确定,有可能是hashSet,也有可能是TreeSet,为了保证唯一性,所以最好复写hashCode方法
作者: yuli2039    时间: 2014-8-8 12:37
南柯一梦 发表于 2014-8-8 10:41
假如一个类要创建很多对象,而这些对象要存储集合不确定,有可能是hashSet,也有可能是TreeSet,为了保证唯 ...

对象存入带hash的集合,如hashSet,hashMap,都要基于hashCode和equals方法,当hashCode方法返回的值一样时,还会调用equals方法判断,如果两个方法返回的都是一致,才判断两个对象是同一个对象,不存入集合(带hash的集合都保证数据是唯一的!)
作者: 怀念黑海岸    时间: 2014-8-8 13:34
本帖最后由 怀念黑海岸 于 2014-8-18 17:56 编辑

       凡是带hash的字眼的都是以哈希表的形式存入数据的,那么哈希表是如何保证元素的唯一性呢? 二叉树类型集合中定义了自己的比较规则来实现元素的唯一性和有序性,那么哈希表呢?一般而言,我们重写hashCode方法和equals方法都是指在使用跟hash表有关的集合时的重写。
       其实哈希表的特点有点儿类似链表,但是链表的节点元素不是单一的,每个节点又是一个新的链表,这个新链表在java中的说法是:桶。每个桶中的元素都是具有相同的hashCode值的,当你传入一个对象时,获得这个对象的hashCode值后会拿到哈希表中去比较,首先找有没有这个地址值的桶,如果没有的话就加上去,这个新加入的元素就是该桶的第一个元素,就叫桶头吧。如果有这个地址值的桶了怎么办?好办,让你这个元素加到这个桶中,我记得好像是加在桶头的,这儿你可以去看下原码,我都好久没接触了,有点记不清了。
        那么我们在新传一个对象进入这个哈希表后他是怎么确保这个元素的唯一性呢?
       首先找地址,就是找对应桶,有则加入这个桶,没则新建一个桶,如果已经有这个桶了,那么他就进入桶中进行遍历,对比里面的元素,对比原则是什么呢?即用equals方法进行比较,都知道java的Object中equals方法比较的是地址,如果这个地址相同呢就是代表相同元素,那你可能说都是趁热new的,不会相同。你考虑过这个问题没:你有qq号,qq号有个id,你有msn,msn又有一个id,那么你明明是一个人呢,却出现两个完全不同的属性,那么你是不是一个人呢,肯定还是嘛。所以我们要定义自己比较规则的equals方法,这才能真正保证你存入元素的唯一性。。
       这也就是为什么hashcode和equals方法要一起重写的原因了。。
      
作者: ┣┫流枫    时间: 2014-8-8 13:39
怀念黑海岸 发表于 2014-8-8 13:34
凡是带hash的字眼的都是以哈希表的形式存入数据的,那么哈希表是如何保证元素的唯一性呢? TreeSet ...

满满的高大上




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2