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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱弋 初级黑马   /  2012-8-10 12:21  /  1657 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


毕老师视频中说到在hashset集合中存入元素时,会先比较元素的哈希值,若相同再equals比较。
请教下各位:但这里比较完后,为什么每个元素还会调用一次hashcode()方法
预期运行结果:
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
[Person@d09b2415, Person@d09b2429, Person@d09b243d]

实际运行结果:(附件有图)
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
wang01hashcode
wang02hashcode
wang03hashcode

[Person@d09b2415, Person@d09b2429, Person@d09b243d]
  1. import java.util.*;
  2. class HashSetDemo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 HashSet hs = new HashSet();
  7.                 hs.add(new Person("wang01",11));
  8.                 hs.add(new Person("wang02",12));
  9.                 hs.add(new Person("wang03",13));
  10.                 hs.add(new Person("wang03",13));

  11.                 print(hs);               
  12.         }
  13.         public static void print(Object obj)
  14.         {
  15.                 System.out.println(obj);
  16.         }
  17. }
  18. class Person
  19. {
  20.         private String name;
  21.         private int age;
  22.         Person(String name,int age)
  23.         {
  24.                 this.name = name;
  25.                 this.age = age;
  26.         }
  27.         public String getName()
  28.         {
  29.                 return name;
  30.         }
  31.         public int getAge()
  32.         {
  33.                 return age;
  34.         }
  35.         public boolean equals(Object obj)        //复写equals方法,判断姓名和年龄是否相同。
  36.         {
  37.                 if (!(obj instanceof Person))
  38.                         return false;
  39.                 Person p = (Person)obj;
  40.                 System.out.println(this.getName()+"..equals.."+p.getName());            //调用equals方法时,打印调用对象的姓名和比较对象的姓名。
  41.                 return this.getName().equals(p.getName()) && this.getAge() == p.getAge();        //判断姓名和年龄是否相同,并返回判断结果。
  42.         }
  43.         public int hashCode()        //复写Object类中的hashCode方法,获取仅与姓名和年龄有关的哈希值。
  44.         {
  45.                                    //调用hashCode时,打印出调用对象的姓名+hashcode。
  46.                 System.out.println(getName()+"hashcode");       
  47.                                    
  48.                 return name.hashCode()+age*19;
  49.         }
  50. }
复制代码

1.jpg (40.7 KB, 下载次数: 22)

1.jpg

3 个回复

倒序浏览
因为你没在Person类中重写toString方法,所以在输出时调用的是Object的toString方法,该方法的返回值是getClass().getName() + '@' + Integer.toHexString(hashCode()),所以还会调用一次hashcode方法
回复 使用道具 举报
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
wang01hashcode
wang02hashcode
wang03hashcode
  1. import java.util.*;
  2. class HashSetDemo
  3. {
  4. public static void main(String[] args)
  5. {
  6. HashSet hs = new HashSet();
  7. hs.add(new Person("wang01",11));
  8. hs.add(new Person("wang02",12));
  9. hs.add(new Person("wang03",13));
  10. hs.add(new Person("wang03",13));

  11. print(hs);
  12. }
  13. public static void print(Object obj)
  14. {
  15. System.out.println(obj);
  16. }
  17. }
  18. class Person
  19. {
  20. private String name;
  21. private int age;
  22. Person(String name,int age)
  23. {
  24. this.name = name;
  25. this.age = age;
  26. }
  27. public String getName()
  28. {
  29. return name;
  30. }
  31. public int getAge()
  32. {
  33. return age;
  34. }
  35. public boolean equals(Object obj) //复写equals方法,判断姓名和年龄是否相同。
  36. {
  37. if (!(obj instanceof Person))
  38. return false;
  39. Person p = (Person)obj;
  40. System.out.println(this.getName()+"..equals.."+p.getName()); //调用equals方法时,打印调用对象的姓名和比较对象的姓名。
  41. return this.getName().equals(p.getName()) && this.getAge() == p.getAge(); //判断姓名和年龄是否相同,并返回判断结果。
  42. }
  43. public int hashCode() //复写Object类中的hashCode方法,获取仅与姓名和年龄有关的哈希值。
  44. {
  45. //调用hashCode时,打印出调用对象的姓名+hashcode。
  46. System.out.println(getName()+"hashcode");

  47. return name.hashCode()+age*19;
  48. }
  49. }
复制代码
hs.add(new Person("wang01",11));
hs.add(new Person("wang02",12));
hs.add(new Person("wang03",13));往Hashset集合中存储对象时,程序会先调用hashcode方法,给每一个传入的对象设置一个哈希值,这一步中你的hashcode方法中有了System.out.println(getName()+"hashcode"); 语句,所以有了一开始的三句打印语句,当hashset集合中存入相同的元素时hs.add(new Person("wang03",13));也是先调用hashcode方法,所以依然有了wang03hashcode的打印语句,发现哈希值相同后,程序执行equals方法,这时就有了System.out.println(this.getName()+"..equals.."+p.getName()); //调用equals方法时,打印调用对象的姓名和比较对象的姓名。所以wang03..equals..wang03的语句,最后的print(hs); 语句因为并没有覆盖toString()方法,所以执行的还是Object类中的toString方法,

方法的源代码如下:
getClass().getName() + '@' + Integer.toHexString(hashCode())
现在楼主明白了吧

回复 使用道具 举报
明白了。谢谢两位。问题已解决。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马