黑马程序员技术交流社区

标题: 关于哈希值和数据地址的关系 [打印本页]

作者: xieshuhua    时间: 2012-5-17 00:21
标题: 关于哈希值和数据地址的关系
今天重新学习了HashSet课程。发现如果新建一个HashSet对象,添加字符串和数字元素时,不能重复添加;(类似==,不过127以上也不能添加)
添加重复对象时,安装毕老师讲的没有问题,可是如果添加相同的Integer对象则仍然不成功。
总结下: 1   ,100000,  "Good luck"  , new Integer(10000)  ,new String("Good luck")---------不成功
                new xx(1)    new yy(1,1)                                                                           ----------成功
书上讲new出来的对象都会分配不同的地址。不同的地址相同的内容,但是哈希值相同,这是什么原理。
  1. import java.util.HashSet;
  2. import java.util.Iterator;
  3. class student {
  4. student (int x){
  5. this.x=x;
  6. };
  7. int x;
  8. }
  9. public class AbsDem{
  10. public static void main(String[] args1) {
  11. HashSet xx=new HashSet();
  12. String x=new String("Good luck");
  13. String y=new String("Good luck");
  14. xx.add(x);
  15. xx.add(y);
  16. xx.add(new student(1));
  17. xx.add(new student(1));
  18. System.out.println(x==y);
  19. Iterator it=xx.iterator();
  20. while(it.hasNext())
  21. System.out.println(it.next());
  22. }
  23. }
复制代码

作者: 袁冬梅    时间: 2012-5-17 00:36
书上讲new出来的对象都会分配不同的地址。不同的地址相同的内容,但是哈希值相同,这是什么原理。

不太懂你这句话的意思,你描述详细点,把你要表达的表达出来一下吧
作者: 黑马罗坚    时间: 2012-5-17 00:40
你的Student类没有覆盖哈希 所以可以添加
String Integer覆盖了哈希方法  相同值的对象返回的HASHCODE相同 在根据EQUALS判断相同所以添加不成功
作者: xieshuhua    时间: 2012-5-17 00:40
袁冬梅 发表于 2012-5-17 00:36
书上讲new出来的对象都会分配不同的地址。不同的地址相同的内容,但是哈希值相同,这是什么原理。

不太懂 ...

哈希值 主要是 地址和内容 的组合映射吧。不同地址 相同内容 产生的映射相同,不应该啊。
作者: 黑马罗坚    时间: 2012-5-17 00:41
如果String和Integer没覆盖hashCode和equals方法也会跟你的Student类一样
作者: xieshuhua    时间: 2012-5-17 00:48
nailsoul 发表于 2012-5-17 00:41
如果String和Integer没覆盖hashCode和equals方法也会跟你的Student类一样

你的意思是 String和Integer内部已经复写了hashCode和equals方法了。我找了下源文件,果然。。。
太谢谢你了,另外附上我找的源文件复写。。。

hashCode.png (4.7 KB, 下载次数: 65)

hashCode.png

作者: 袁冬梅    时间: 2012-5-17 00:51
谢述华 发表于 2012-5-17 00:40
哈希值 主要是 地址和内容 的组合映射吧。不同地址 相同内容 产生的映射相同,不应该啊。 ...


还是没搞懂你的产生的映射相同是什么意思。。。。

对象在没有对它的Hashcode进行重写的时候,我们通过hashCode方法获取到的对象的地址都是它在内存中的地址,这个地址是唯一的。

所以,Student s = new Student("zhangsan");Student s1 = new Student("zhangsan");两个对象存储的地址不同,那么我们返回的hashCode就是它们自己的堆内存中的首地址

然后,创建的这两个对象里面的内容其实是相同的,都是zhangsan这个学生,对吧。但是,其实它们是不同的对象,存在堆中不同的位置,那么hashCode获取到的就是那个地址,对应的自然是不同的对像,然后你说的映射相同就不存在。。因为这里其实是不同的键对应了不同的值了。OK
作者: 薄炳鑫    时间: 2012-5-17 02:15
在java核心技术一书中说到过String类的hashcode是通过内容导出的,所以不同的对象,相同的内容会生成同样的hashcode。




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