A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孔肖 中级黑马   /  2012-9-2 17:14  /  1813 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孔肖 于 2012-9-2 17:59 编辑

如果两个对象的equals比较相等的话,是不是一定要让他们的hashCode值也相等?为什么

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
不是滴,你可以先理解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的范围也会包异常了。
      纯手工党,希望能帮到你!

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 孙鑫 于 2012-9-2 17:41 编辑

两个对象值相同(x.equals(y) == true),则一定有相同的hash code。
如果两个对象equals()方法比较相同的话,它们的hash码不同,就会造成同一个对象在HashSet中可能有两个版本。
所以只要两个对象相同,必须保证他们的hashcode也相同以保证一个对象在HashSet中的位置唯一确定。
回复 使用道具 举报
  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:38
不是滴,你可以先理解HashSet的底层比较的顺序
  |--Set:元素时无序的(元素取出和存储都是无序的),元素不 ...

哦,明白了。十分感谢:handshake
回复 使用道具 举报
孙鑫 发表于 2012-9-2 17:39
两个对象值相同(x.equals(y) == true),则一定有相同的hash code。
如果两个对象equals()方法比较相同的话 ...

哦。明白了。十分感谢:handshake
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马