黑马程序员技术交流社区
标题: 对HashSet的大胆尝试,有问题吗? [打印本页]
作者: 万琪 时间: 2013-6-29 11:29
标题: 对HashSet的大胆尝试,有问题吗?
本帖最后由 孙百鑫 于 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 ;
}
这样做有问题吗?。。啥问题,,,
作者: 王靖远 时间: 2013-6-29 11:47
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张三李四不就同一人了吗
作者: 花伟昌 时间: 2013-6-29 11:52
你的代码中,覆写了hashCode()方法 equals()返回true,但是你只是通过两个属性:name,age,来判断的,如果还有其他属性的呢?(比如一种情况:两个人姓名,年龄虽然不同,但运算结果相同,这种情况不是没有可能的)。通过一些属性的数值运算有些时候并不能很准确。
覆写equals方法,(如:比较两个人的姓名等等)可以再进行一次判断。
作者: 万琪 时间: 2013-6-29 12:14
王靖远 发表于 2013-6-29 11:47
这样做可能有隐患。 zhangsan.name.hashcode()+zhangsan.age*7 == lisi.name.hashchode()+lisi.age*7 那张 ...
。。。name的hashcode是不同的。。
作者: 万琪 时间: 2013-6-29 12:17
。。这个name+年龄就像是数据库里定义的主键,,,是唯一表示,,使用hashcode正是要避免主键重复,,你的这个理由不充分哦,,
作者: 王靖远 时间: 2013-6-29 12:25
这个我不知道哦,既然name的hashoCode是不同的,那为什么age还要*7呢?当时看老毕的视频 ,也提到了要复写equals方法再判断一次
作者: 万琪 时间: 2013-6-29 12:28
还是用数据库的例子,,可以用一列做主键,,也可以用两列,,只是需求不同罢了
作者: 秩宇 时间: 2013-6-29 13:00
哈希算法对不同的值是有可能产生相同的哈希码的,这被称为散列冲突(hash collision),这时候就要通过equals方法比较两个对象是否相同。
作者: 张云杰 时间: 2013-6-29 13:17
不用猜测了.. 本来根据hashcode其实是可以的, 因为每次开辟对象的空间 他是不一样的, equlas 可以不重写.. 但是, 怕就怕在 两个对象的引用 被指到同一个内存地址中, 还记得老毕说过么? 相同的值 是直接引用的 而是不开辟新的空间..
所以这时候就需要判断 是不是一样了.. 不知道这个解释 是否合阁下的胃口
作者: 万琪 时间: 2013-6-29 13:20
很专业啊,百度上市这么说的吗?
作者: 万琪 时间: 2013-6-29 13:22
呵呵,,和我想得一样,,是为了代码严谨,,编程就是要严谨啊- -
作者: 张云杰 时间: 2013-6-29 13:25
还有一方面 是为了符合规则
就是那个 如果 他们的equals true. 那么他们的hashcode必须相等,
如果hashcode相等, 他们的equals不一定true
作者: 陈雨 时间: 2013-6-29 16:07
就是有可能hashcode相同,但是对象的内容不一样,比如7+1和1+7,这样两个hashcode一样,添加时,第二个对象就添加不进去,但是他们确实不是同一对象。
作者: 万琪 时间: 2013-6-29 16:23
7+1和1+7不是一个对象?他是对象?。。如果你说的是 包装类,,也是一个对象
作者: 陈雨 时间: 2013-6-29 16:37
我是讲person对象啊,你里面不是有name和age字段吗?往集合里添加两个对象时,new person("张三",1),new person("李四",7),我姑且假设他们的hashCode分别是49+7,7+49当然字符串的hashCode计算很复杂和int的不一样,你这两个person对象是一样的吗?因为你的equals方法返回的是true,所以往集合里面添加的时候第二个李四的对象就添加不进去了。
作者: 万琪 时间: 2013-6-29 16:40
,,这种几率很小的,比中彩票还低,,但也不排除,,代码应该是严谨的- -哈哈
作者: 秩宇 时间: 2013-6-29 22:41
万琪 发表于 2013-6-29 13:20
很专业啊,百度上市这么说的吗?
我习惯对自己并不是完全确定的问题时查找资料后再回答,而且尽可能的详细,我认为这是对自己和提问者都是有帮助的。但是我的回答都是自己的理解,可以告诉你我参考的是《think in java》 的第十一章 对象的集合 的 散列算法与hash数 小结 和 《java核心技术-基础知识》中的第五章 继承 的第二小节 object:所有类的超类 和第十三章 集合 的 第二小结 具体的集合 的 第三部分 散列集 。所以,我对你怀疑我抄袭百度的回复表示强烈不满,要求你删除回复并向我道歉,同时保留向版主投诉的权利。
作者: 万琪 时间: 2013-6-30 00:28
嘿嘿,,哥们,,你误会了,,谁说百度的就是抄袭,,我就经常百度,,有何不可,,
另外,,你的回答不错哦,,think in java 我都没有看完,,真心不错啊
作者: 秩宇 时间: 2013-6-30 13:32
那很抱歉,是我反应过度了,对不起。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |