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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 万琪 金牌黑马   /  2013-6-29 11:29  /  3162 人查看  /  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 个回复

正序浏览
万琪 发表于 2013-6-30 00:28
嘿嘿,,哥们,,你误会了,,谁说百度的就是抄袭,,我就经常百度,,有何不可,,
另外,,你的回答不 ...

那很抱歉,是我反应过度了,对不起。
回复 使用道具 举报
秩宇 发表于 2013-6-29 22:41
我习惯对自己并不是完全确定的问题时查找资料后再回答,而且尽可能的详细,我认为这是对自己和提问者都是 ...

嘿嘿,,哥们,,你误会了,,谁说百度的就是抄袭,,我就经常百度,,有何不可,,
另外,,你的回答不错哦,,think in java 我都没有看完,,真心不错啊
回复 使用道具 举报
秩宇 来自手机 中级黑马 2013-6-29 22:41:21
17#
万琪 发表于 2013-6-29 13:20
很专业啊,百度上市这么说的吗?

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

,,这种几率很小的,比中彩票还低,,但也不排除,,代码应该是严谨的- -哈哈
回复 使用道具 举报
万琪 发表于 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:07
就是有可能hashcode相同,但是对象的内容不一样,比如7+1和1+7,这样两个hashcode一样,添加时,第二个对象 ...

7+1和1+7不是一个对象?他是对象?。。如果你说的是 包装类,,也是一个对象
回复 使用道具 举报
就是有可能hashcode相同,但是对象的内容不一样,比如7+1和1+7,这样两个hashcode一样,添加时,第二个对象就添加不进去,但是他们确实不是同一对象。

评分

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

查看全部评分

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

还有一方面 是为了符合规则
就是那个 如果 他们的equals true. 那么他们的hashcode必须相等,
如果hashcode相等, 他们的equals不一定true
回复 使用道具 举报
张云杰 发表于 2013-6-29 13:17
不用猜测了.. 本来根据hashcode其实是可以的, 因为每次开辟对象的空间 他是不一样的,  equlas 可以不重写.. ...

呵呵,,和我想得一样,,是为了代码严谨,,编程就是要严谨啊- -
回复 使用道具 举报
秩宇 发表于 2013-6-29 13:00
哈希算法对不同的值是有可能产生相同的哈希码的,这被称为散列冲突(hash collision),这时候就要通过equa ...

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

所以这时候就需要判断 是不是一样了.. 不知道这个解释 是否合阁下的胃口
回复 使用道具 举报
秩宇 来自手机 中级黑马 2013-6-29 13:00:41
8#
哈希算法对不同的值是有可能产生相同的哈希码的,这被称为散列冲突(hash collision),这时候就要通过equals方法比较两个对象是否相同。

评分

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

查看全部评分

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

还是用数据库的例子,,可以用一列做主键,,也可以用两列,,只是需求不同罢了
回复 使用道具 举报
万琪 发表于 2013-6-29 12:14
。。。name的hashcode是不同的。。

这个我不知道哦,既然name的hashoCode是不同的,那为什么age还要*7呢?当时看老毕的视频 ,也提到了要复写equals方法再判断一次
回复 使用道具 举报
花伟昌 发表于 2013-6-29 11:52
你的代码中,覆写了hashCode()方法 equals()返回true,但是你只是通过两个属性:name,age,来判断的,如果 ...

。。这个name+年龄就像是数据库里定义的主键,,,是唯一表示,,使用hashcode正是要避免主键重复,,你的这个理由不充分哦,,
回复 使用道具 举报
王靖远 发表于 2013-6-29 11:47
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张 ...

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

评分

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

查看全部评分

回复 使用道具 举报
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张三李四不就同一人了吗

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马