黑马程序员技术交流社区

标题: 求大神解答一下集合问题 [打印本页]

作者: LOVE你的ME    时间: 2014-11-30 23:45
标题: 求大神解答一下集合问题
看视频到了集合部分,有了点疑惑(其实算是有点钻牛角尖吧)
和集合没多大关系,关于HashSet的HashCode方法和equals方法
                           equals方法比较的不是地址值吗?地址值不就是哈希值吗?哈希值一样equals完不一样呢。
  1. package lianxibao2;

  2. public class Demo01 {
  3.         public static void main(String[] args) {

  4.                 Person p1 = new Person("lisi03", 33);
  5.                 Person p2 = new Person("lisi03", 33);
  6.                 System.out.println(p1);// 结果:lianxibao2.Person@3c
  7.                 System.out.println(p2);// 结果:lianxibao2.Person@3c
  8.                 System.out.println(p1.equals(p2));// 结果false
  9.         }
  10. }

  11. class Person {
  12.         private String name;
  13.         private int age;

  14.         // 重写了hashCode这个方法
  15.         public int hashCode() {
  16.                 System.out.println("hashCode");
  17.                 return 60;
  18.         }

  19.         Person(String name, int age) {
  20.                 this.name = name;
  21.                 this.age = age;
  22.         }
  23. }
复制代码




作者: 15621506590    时间: 2014-11-30 23:57
hashCode比较的是哈希值,在java中每一个对象都有一个哈希值,也就是地址值,但每一个对象的哈希值都不相同,所以hashCode也不同。而equals不仅比较了hashCode是否相同,还比较了对象的内容是否相同。
作者: LOVE你的ME    时间: 2014-12-1 00:02
15621506590 发表于 2014-11-30 23:57
hashCode比较的是哈希值,在java中每一个对象都有一个哈希值,也就是地址值,但每一个对象的哈希值都不相同 ...

内容,你是指  "lisi03", 33  这个吗 ?内容上面代码也是相同的啊
              
作者: 船长    时间: 2014-12-1 00:49
LOVE你的ME 发表于 2014-12-1 00:02
内容,你是指  "lisi03", 33  这个吗 ?内容上面代码也是相同的啊
               ...

HashCode比较的算是地址值,如果地址值相同,在用equals去比较对象里面的内容是否相同,此时equals比较的是内容。比如,"lisi03", 33和"lisi02", 33,加入他们的HashCode相同了,equals去比较姓名lisi03和lisi02,如果相同就认为是同一个
作者: LOVE你的ME    时间: 2014-12-1 01:01
我上面的代码中里面内容是相同的啊
  1. Person p1 = new Person("lisi03", 33);
  2. Person p2 = new Person("lisi03", 33);
复制代码




作者: LOVE你的ME    时间: 2014-12-1 01:02
船长 发表于 2014-12-1 00:49
HashCode比较的算是地址值,如果地址值相同,在用equals去比较对象里面的内容是否相同,此时equals比较的 ...


我上面的代码中里面内容是相同的啊
Person p1 = new Person("lisi03", 33);
Person p2 = new Person("lisi03", 33);


作者: FlyFish    时间: 2014-12-1 09:56
本帖最后由 FlyFish 于 2014-12-1 10:05 编辑

Object类对hashCode的描述
如果根据equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
也就是说哈希值相等,对象也可以不相等。

作者: 白金角斗士    时间: 2014-12-1 10:08
LOVE你的ME 发表于 2014-12-1 01:02
我上面的代码中里面内容是相同的啊
Person p1 = new Person("lisi03", 33);
Person p2 = new Person("li ...

这个确实算是牛角尖吧

首先第一点,这两个对象的地址值肯定是不同,尽管内容完全一样
但是当你重写了hashCode之后,那么他们产生的哈希值就会一致
虽然这个时候你调用了equals比较具体的值,结果却是false。
那我们一起看源码吧
public boolean equals(Object obj) {
        return (this == obj);
    }因为这两个始终不为同一对象,所以结果为flase.
作者: as604049322    时间: 2014-12-1 10:52
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

楼主并未覆写 equals 方法,Object 类的 equals 方法是只比较2对象引用是否指向同一对象的。
作者: 十万一千    时间: 2014-12-1 20:04
你的哈希值是自己算出来的 也就是你给的60  但Person默认继承Object,equals方法也被继承过来了; jvm在用对象地址值做equals比较,而你用了一个常数做每个对象的hashcode。
作者: hello_csu    时间: 2014-12-1 20:29
记得equals方法是继承与Obj的,比较的是对象引用,而非对象的内容,而你上面创建
Person p1 = new Person("lisi03", 33);
Person p2 = new Person("lisi03", 33);
实际上P1,P2指向的堆地址是不同的,即对象引用的值肯定是不同的。如果你需要让他相等应该
要重写equal方法,感觉与hashcode完全是没有任何关系的。




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