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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 万琪 金牌黑马   /  2013-6-29 11:29  /  3189 人查看  /  18 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孙百鑫 于 2013-6-30 18:17 编辑

首先科普一下:(大牛掠过)

               HashSet是如何保证元素唯一性的呢?
               是通过元素的两个方法,hashCode和equals来完成。
               如果元素的HashCode值相同,才会判断equals是否为true。
               如果元素的hashcode值不同,不会调用equals。



那么,,是否可以,只通过hashcode来完成这一任务呢?。。。

以下我做了大胆尝试,,,
{:soso_e153:}

      String name ;
       int age ;

       public int hashCode() {
            System. out .println( this. name + "....hashCode");
             return name .hashCode() + age*7;
      }

       public boolean equals(Object obj) {
             return true ;
      }



这样做有问题吗?。。啥问题,,,

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1 神马都是浮云

查看全部评分

18 个回复

倒序浏览
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张三李四不就同一人了吗

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
你的代码中,覆写了hashCode()方法 equals()返回true,但是你只是通过两个属性:name,age,来判断的,如果还有其他属性的呢?(比如一种情况:两个人姓名,年龄虽然不同,但运算结果相同,这种情况不是没有可能的)。通过一些属性的数值运算有些时候并不能很准确。
 覆写equals方法,(如:比较两个人的姓名等等)可以再进行一次判断。

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
王靖远 发表于 2013-6-29 11:47
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张 ...

。。。name的hashcode是不同的。。
回复 使用道具 举报
花伟昌 发表于 2013-6-29 11:52
你的代码中,覆写了hashCode()方法 equals()返回true,但是你只是通过两个属性:name,age,来判断的,如果 ...

。。这个name+年龄就像是数据库里定义的主键,,,是唯一表示,,使用hashcode正是要避免主键重复,,你的这个理由不充分哦,,
回复 使用道具 举报
万琪 发表于 2013-6-29 12:14
。。。name的hashcode是不同的。。

这个我不知道哦,既然name的hashoCode是不同的,那为什么age还要*7呢?当时看老毕的视频 ,也提到了要复写equals方法再判断一次
回复 使用道具 举报
万琪 金牌黑马 2013-6-29 12:28:32
7#
王靖远 发表于 2013-6-29 12:25
这个我不知道哦,既然name的hashoCode是不同的,那为什么age还要*7呢?当时看老毕的视频 ,也提到了要复 ...

还是用数据库的例子,,可以用一列做主键,,也可以用两列,,只是需求不同罢了
回复 使用道具 举报
秩宇 来自手机 中级黑马 2013-6-29 13:00:41
8#
哈希算法对不同的值是有可能产生相同的哈希码的,这被称为散列冲突(hash collision),这时候就要通过equals方法比较两个对象是否相同。

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报 0 1
不用猜测了.. 本来根据hashcode其实是可以的, 因为每次开辟对象的空间 他是不一样的,  equlas 可以不重写.. 但是, 怕就怕在 两个对象的引用 被指到同一个内存地址中,  还记得老毕说过么? 相同的值 是直接引用的 而是不开辟新的空间..

所以这时候就需要判断 是不是一样了.. 不知道这个解释 是否合阁下的胃口
回复 使用道具 举报
秩宇 发表于 2013-6-29 13:00
哈希算法对不同的值是有可能产生相同的哈希码的,这被称为散列冲突(hash collision),这时候就要通过equa ...

很专业啊,百度上市这么说的吗?
回复 使用道具 举报
张云杰 发表于 2013-6-29 13:17
不用猜测了.. 本来根据hashcode其实是可以的, 因为每次开辟对象的空间 他是不一样的,  equlas 可以不重写.. ...

呵呵,,和我想得一样,,是为了代码严谨,,编程就是要严谨啊- -
回复 使用道具 举报
万琪 发表于 2013-6-29 13:22
呵呵,,和我想得一样,,是为了代码严谨,,编程就是要严谨啊- -

还有一方面 是为了符合规则
就是那个 如果 他们的equals true. 那么他们的hashcode必须相等,
如果hashcode相等, 他们的equals不一定true
回复 使用道具 举报
就是有可能hashcode相同,但是对象的内容不一样,比如7+1和1+7,这样两个hashcode一样,添加时,第二个对象就添加不进去,但是他们确实不是同一对象。

评分

参与人数 1技术分 +1 收起 理由
孙百鑫 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
陈雨 发表于 2013-6-29 16:07
就是有可能hashcode相同,但是对象的内容不一样,比如7+1和1+7,这样两个hashcode一样,添加时,第二个对象 ...

7+1和1+7不是一个对象?他是对象?。。如果你说的是 包装类,,也是一个对象
回复 使用道具 举报
万琪 发表于 2013-6-29 16:23
7+1和1+7不是一个对象?他是对象?。。如果你说的是 包装类,,也是一个对象 ...

我是讲person对象啊,你里面不是有name和age字段吗?往集合里添加两个对象时,new person("张三",1),new person("李四",7),我姑且假设他们的hashCode分别是49+7,7+49当然字符串的hashCode计算很复杂和int的不一样,你这两个person对象是一样的吗?因为你的equals方法返回的是true,所以往集合里面添加的时候第二个李四的对象就添加不进去了。
回复 使用道具 举报
陈雨 发表于 2013-6-29 16:37
我是讲person对象啊,你里面不是有name和age字段吗?往集合里添加两个对象时,new person("张三",1),ne ...

,,这种几率很小的,比中彩票还低,,但也不排除,,代码应该是严谨的- -哈哈
回复 使用道具 举报
秩宇 来自手机 中级黑马 2013-6-29 22:41:21
17#
万琪 发表于 2013-6-29 13:20
很专业啊,百度上市这么说的吗?

我习惯对自己并不是完全确定的问题时查找资料后再回答,而且尽可能的详细,我认为这是对自己和提问者都是有帮助的。但是我的回答都是自己的理解,可以告诉你我参考的是《think in java》 的第十一章 对象的集合 的 散列算法与hash数 小结 和 《java核心技术-基础知识》中的第五章 继承 的第二小节 object:所有类的超类 和第十三章 集合 的 第二小结 具体的集合 的 第三部分 散列集  。所以,我对你怀疑我抄袭百度的回复表示强烈不满,要求你删除回复并向我道歉,同时保留向版主投诉的权利。
回复 使用道具 举报
秩宇 发表于 2013-6-29 22:41
我习惯对自己并不是完全确定的问题时查找资料后再回答,而且尽可能的详细,我认为这是对自己和提问者都是 ...

嘿嘿,,哥们,,你误会了,,谁说百度的就是抄袭,,我就经常百度,,有何不可,,
另外,,你的回答不错哦,,think in java 我都没有看完,,真心不错啊
回复 使用道具 举报
万琪 发表于 2013-6-30 00:28
嘿嘿,,哥们,,你误会了,,谁说百度的就是抄袭,,我就经常百度,,有何不可,,
另外,,你的回答不 ...

那很抱歉,是我反应过度了,对不起。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马