黑马程序员技术交流社区

标题: 关于hashCode相同时是如何比较对象是否相同的 [打印本页]

作者: 玥夜    时间: 2014-8-16 15:36
标题: 关于hashCode相同时是如何比较对象是否相同的
本帖最后由 玥夜 于 2014-8-16 17:03 编辑

只是覆写了Preson的hashCode方法;没有覆写equals方法,也就是new出来的对象都是一个地址值;可是为什么这两个对象不是一个呢:Object中的equals不是比较的就是地址值麽。。。。。。。。。纠结  请大神指点一二:lol  谢谢

1.png (89.08 KB, 下载次数: 59)

1.png

作者: yuZhe_toString    时间: 2014-8-16 16:01
本帖最后由 yuZhe_toString 于 2014-8-16 16:03 编辑

貌似你的控制台输出的不是当前类的真实结果。两个对象地址不应该相同。一看你那地址就是假的。
作者: 杨庆雷    时间: 2014-8-16 16:03
本帖最后由 杨庆雷 于 2014-8-16 16:10 编辑
  1. public class HashCodeTest {

  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 Person1 p1 = new Person1();
  5.                 Person1 p2 = new Person1();
  6.                
  7.                 int a = p1.hashCode();
  8.                 int b = p2.hashCode();
  9.                 System.out.println(a == b);
  10.                 System.out.println(p1.equals(p2));
  11.         }

  12. }

  13. class Person1{

  14.         @Override
  15.         public boolean equals(Object arg0) {
  16.                 // TODO Auto-generated method stub
  17.                 return true;
  18.         }

  19.         @Override
  20.         public int hashCode() {
  21.                 // TODO Auto-generated method stub
  22.                 return 2;
  23.         }
  24.         
  25. }<span style="background-color: rgb(255, 255, 255); line-height: 2.2em;"></span>
复制代码

作者: 玥夜    时间: 2014-8-16 16:11
杨庆雷 发表于 2014-8-16 16:03

我知道会比较equals的  如果Person类不覆写equals方法呢  我就是想知道他怎么比较的  Person继承了Object的equals 不就是比较地址值麽
作者: 玥夜    时间: 2014-8-16 16:12
yuZhe_toString 发表于 2014-8-16 16:01
貌似你的控制台输出的不是当前类的真实结果。两个对象地址不应该相同。一看你那地址就是假的。 ...

这个地址值 是我自己设定的  这是可以的  学到Collection中HashCode的时候就有了
作者: 杨庆雷    时间: 2014-8-16 16:15
玥夜 发表于 2014-8-16 16:11
我知道会比较equals的  如果Person类不覆写equals方法呢  我就是想知道他怎么比较的  Person继承了Object ...

hashCode比较的是地址啊  
boolean equals(Object obj)
          指示其他某个对象是否与此对象“相等”。

对象相等的前提是哈希值相等   
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。


作者: z-翔    时间: 2014-8-16 16:23
我一直怀疑所谓的内存地址和哈希值根本不是同一个东西,试想一下,
你创建一个类,该类覆写了hashCode方法,
使其返回相同的值,如果内存地址和哈希值是同一个东西,
那岂不是之后new出来的所有对象的引用都是同一个,
这好像不科学,但是我在网上查资料,也没有找到相关的东西,
不过,我还是认为这两者应该不是同一个东西,如果这么说,就能解释你的代码了
作者: yuZhe_toString    时间: 2014-8-16 16:33
玥夜 发表于 2014-8-16 16:12
这个地址值 是我自己设定的  这是可以的  学到Collection中HashCode的时候就有了 ...

java还能给对象指定地址?new了两个新对象,地址能相同?这不科学
作者: cs8630323    时间: 2014-8-16 16:35
本帖最后由 cs8630323 于 2014-8-16 16:47 编辑

    public boolean equals(Object obj) {
        return (this == obj);
    }
这个是源码,有什么不懂就看源码,一目了然。
作者: yuZhe_toString    时间: 2014-8-16 17:04
yuZhe_toString 发表于 2014-8-16 16:33
java还能给对象指定地址?new了两个新对象,地址能相同?这不科学

哦哦  之前是我错,你重写了hashCode().这回结果就说通了.



System.out.println(p1).打印时调用的是p1中的toString方法。
由于没有重写,所以调用父类的方法。下面是Object源码
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
上面的打印值不能看作真实地址。

如果没有重写equals方法的话,那么他会调用父类的equals方法,父类equals方法确实比较的是两个对象的地址。下面是Object类源码
public boolean equals(Object obj) {
        return (this == obj);
}
作者: wqmsan    时间: 2014-8-16 17:11
1.自定义对象重写了hashCode方法
2.在堆内存中new了两个实体
3.通过输出语句打印System.out.println(p1)其实是调用Object类中的toString方法System.out.println(p1.toString)
     而toString源码是
   public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
   只是保证你打印出来的   “包名  类名@  hashCode ” 值是一至的  
    并不是真正在堆内存中存在的地址值
4.因为毕竟在堆内存中产生了两个实体。而equals和==相比较的是内存中的地址值,它是两个对象,就会开辟
   两片空间,真正的内存的值是不同的。
使用System.out.println()输出的是对象通过计算得出的的哈希码,你只是保证了哈希码是一致的。而非内存地址。在Java中是不可能得到对象真正的内存地址的,因为Java中堆是由JVM管理的不能直接操作。


这是我的理解,希望对你有帮助。
作者: 陈君    时间: 2014-8-16 17:59
你还没覆盖的时候hashCode方法返回的是地址。但是你覆盖之后你自己写的hashCode返回出来的就不是地址址。分析下就知道,地址值是不可能相同的。java对象中的hashCode也只是把地址值取出来返回。而不是把算出来的值拿去作为数据存放的地址。
作者: 玥夜    时间: 2014-8-16 18:54
陈君 发表于 2014-8-16 17:59
你还没覆盖的时候hashCode方法返回的是地址。但是你覆盖之后你自己写的hashCode返回出来的就不是地址址。分 ...

恩 知道了 谢谢
作者: 戰傷    时间: 2014-8-17 08:38
Person类只覆写了hashCode方法,返回同一个值,当比较两个对象的哈希值的时候,返回的就会是同一个哈希值.
但是你没有覆写equals方法,Object类中equals还是比较的是对象在堆内存中的地址,new出来两个对象,两个对象在内存的地址当然不一样.
作者: 君行    时间: 2014-8-17 10:14
学习了                                       
作者: 碎流    时间: 2014-8-17 10:40
new出来的对象就不可能是一个对象....所以地址值是肯定不同的,




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