黑马程序员技术交流社区

标题: 【已解决】关于equals和hashCode的问题 [打印本页]

作者: 孔肖    时间: 2012-9-2 17:14
标题: 【已解决】关于equals和hashCode的问题
本帖最后由 孔肖 于 2012-9-2 17:59 编辑

如果两个对象的equals比较相等的话,是不是一定要让他们的hashCode值也相等?为什么
作者: 程有愿    时间: 2012-9-2 17:38
不是滴,你可以先理解HashSet的底层比较的顺序
  |--Set:元素时无序的(元素取出和存储都是无序的),元素不可以重复。和collection方法一致
       |--HashSet:底层结构是哈希表。(判断是否相同除了要判断哈希值,还要判断对象是否相同),

值得注意的是hashset的add方法返回的是真与假(HashSet是如何保证元素的唯一性的呢?是通过2个方

法hashCode和equals来完成,如果元素的HashCode值相同,才会判断equals是否相同,如果元素的

hashcode值不同,不会调用equals。所以根据元素的特性来建立不同的hashcode效率要高些)、
对应元素是否存在,以及删除等操作依赖的方法也是hashcode和equals方法,线程时不同步的。
这里也就是说equals的判断是建立在HashCode的基础之上的,所以说假如你所存入的2对象都是new出来的,但这2个对象的属性都是一样的,如果不去把他们的hashcode
通过复写object的方法设置为相等的话,那么这2个对象都可以存入到这个HashSet集合中,就违背了HashSet的元素的不可重复性,里面就可以放入2个属性相同而hashcod
不同的对象,但在一般情况下我们是认为他们相同的,所以要设置相同的hashcode来确保他们能进行自定义的equals比较,确保他们只能存入一个。
那么另外,如果所有的对象所设置的HashCode都设置为一样的话,这样,所以需要被存入的元素都需要比较,就是低效率了,所以我们可以把hashcode的返回值定义为何这些对象的特有属性相关的表达式  譬如person一个对象p: return  p.name.hashcode()+p.age,当然这样定义也有他的弊端,也难免不会遇到2边相加出现相等的情况,好比20+40=40+20一样,不太安全,但一般这样出现的几率小,不安全,还有一点就是这样定义的话,一般表达式不能使其范围过大,超过了hashcode的范围也会包异常了。
      纯手工党,希望能帮到你!

作者: 孙鑫    时间: 2012-9-2 17:39
本帖最后由 孙鑫 于 2012-9-2 17:41 编辑

两个对象值相同(x.equals(y) == true),则一定有相同的hash code。
如果两个对象equals()方法比较相同的话,它们的hash码不同,就会造成同一个对象在HashSet中可能有两个版本。
所以只要两个对象相同,必须保证他们的hashcode也相同以保证一个对象在HashSet中的位置唯一确定。
作者: 王自强    时间: 2012-9-2 17:51
  HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
  HashSet是如何保证元素唯一性的呢?
  是通过元素的两个方法,hashCode和equals来完成。
  如果元素的HashCode值相同,才会判断equals是否为true.为true表示两个元素相等,否则不相等。
  如果元素的hashCode值不同,表明两元素不相等,就不会再调用equals进行进一步的判断了。
对于HashSet集合中的元素,尽量复写public int hashCode()和public boolean equals(Object obj)
  注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
作者: 孔肖    时间: 2012-9-2 17:56
程有愿 发表于 2012-9-2 17:38
不是滴,你可以先理解HashSet的底层比较的顺序
  |--Set:元素时无序的(元素取出和存储都是无序的),元素不 ...

哦,明白了。十分感谢:handshake
作者: 孔肖    时间: 2012-9-2 17:56
孙鑫 发表于 2012-9-2 17:39
两个对象值相同(x.equals(y) == true),则一定有相同的hash code。
如果两个对象equals()方法比较相同的话 ...

哦。明白了。十分感谢:handshake




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