黑马程序员技术交流社区

标题: 关于class类中的哈希值问题 [打印本页]

作者: wingli    时间: 2014-9-30 16:32
标题: 关于class类中的哈希值问题
求教大神,毕老师在写class函数时,有时候会写hashCode()和equals()方法,有时候又没有写。究竟什么时候需要写hashCode()和equals()方法呢?

作者: 哈达洋    时间: 2014-9-30 17:49
那你使用的东西底层是否需要用到hashCode和equals方法。比如你在用集合的时候,如果采用的hashset,它底层保证唯一性的原理是先判断hashcode,在判断equals,这个时候就需要覆写。而treeset底层则调用的是compareto方法,那就不需要覆写
作者: liuxiang    时间: 2014-9-30 18:20
hashset存储数据时会先调用hashcode()比较哈希值,哈希值相同再调用equal()比较元素内容是否相同,看需求可以在对象代码块中覆写这两个函数
作者: 雨下阳光    时间: 2014-9-30 18:32
在你用到Set集合中的子集合HashSet时,这时要保证集合元素的唯一性,就要覆写hashCode()和equals()方法。给你个例子参考吧
  1. /*
  2. 往hashSet集合中存入自定对象
  3. 姓名和年龄相同为同一个人,重复元素。去除重复元素
  4. 思路:1、对人描述,将人的一些属性等封装进对象
  5.           2、定义一个HashSet容器,存储人对象
  6.           3、取出

  7. */
  8. import java.util.*;

  9. //人描述
  10. class Person
  11. {
  12.         private String name;
  13.         private int age;

  14.         Person(String name,int age)
  15.         {
  16.                 this.name=name;
  17.                 this.age=age;
  18.         }

  19.         public String getName()
  20.         {
  21.                 return name;
  22.         }

  23.         public int getAge()
  24.         {
  25.                 return age;
  26.         }

  27.         public boolean equals(Object obj)
  28.         {
  29.                 if(!(obj instanceof Person))
  30.                         return false;
  31.                 Person p=(Person)obj;
  32.                 return this.name.equals(p.name)&&this.age==p.age;
  33.         }

  34.         public int hashCode()
  35.         {
  36.                 return this.name.hashCode()+this.age;
  37.         }
  38. }
  39. class  HashSetTest
  40. {
  41.         public static void main(String[] args)
  42.         {
  43.                 HashSet h=new HashSet();
  44.                 h.add(new Person("shenm",10));
  45.                 h.add(new Person("shenm2",6));
  46.                 h.add(new Person("shenm1",30));
  47.                 h.add(new Person("shenm0",10));
  48.                 h.add(new Person("shenm0",10));
  49.                
  50.                 getOut(h);

  51.         }

  52.         //取出元素
  53.         public static void getOut(HashSet h)
  54.         {
  55.                 for (Iterator it=h.iterator(); it.hasNext(); )
  56.                 {
  57.                         Person p=(Person)it.next();
  58.                         sop(p.getName()+"..."+p.getAge());
  59.                 }
  60.         }

  61.         //打印
  62.         public static void sop(Object obj)
  63.         {
  64.                 System.out.println(obj);
  65.         }
  66. }
复制代码

作者: ζ_____________    时间: 2014-9-30 18:48
这个地方就需要判断需要使用什么样的集合来判断其元素的唯一性了. 比如 HashSet的判断唯一性是利用
(1)复写hashCode():利用成员中String自带的hashCode()来添加hashcode的条件,这样就将int成员条件加进去再判断两个元素是否相等.减少了相同hashcode之间的判断次数.为了尽量保证哈希值的唯一性,可以将int成员增加条件判断;String.hashCode()+int*一个数字.  这种形式来判断元素的hashCode的唯一性.
(2)复写equals():元素的HashCode值相同,才会判断equals是否为true. 所以要再进行一次元素中equals的对比,这里一般会判断该元素中的成员的私有属性是否相等,来进一步判断元素是否唯一.  记住! 该equals方法的继承Object中的, 所以传入之后是以多态的形式存在的. 所以:第一步先判断该对象的类型是否是要判断的对象(传入的对象instanceof(对象))  如果不是抛出异常,  如果是的话 ,  将这个传入的对象进行向下转型, 再进行该对象中的特有属性比较.
这样来判断对象的唯一性.   

对于数据结构不同,所依赖的判断方法也是不同的.  ArrayList依赖的是equals, HashSet先依赖hashcode然后equals.


之前总结的... ^^ 希望对您有所帮助.

作者: 菜鸟一号    时间: 2014-9-30 19:27
非基本类型的一般都重写




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