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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

soarky

初级黑马

  • 黑马币:9

  • 帖子:16

  • 精华:0

© soarky 初级黑马   /  2014-4-11 17:05  /  979 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

hashset为什么要重写hashCode() 和 equals() 方法?以及重写时的代码解析?

点评

这两个方法只对要存入hashSet集合的自定义对象,要写,hashCode()将地址按照自己定义的方式给出定制,equals()吧,再存入集合的时底层自动调用..  发表于 2014-4-11 17:18

4 个回复

倒序浏览
object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode,那么我们再new一个新的对象,
当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致,如在存储散列集合时(如Set类),将会存储了两个值一样的对象,
导致混淆,因此,就也需要重写hashcode()

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

回复 使用道具 举报
hashset判断集合中的元素是否唯一,是通过元素的两个方法,hashCode和equals方法来完成,如果元素的HashCode值相同,才会判断equals是否为true,如果元素的HashCode值不同,才会调用equals,复写这两个方法的代码解析如下:
  1. public static int hashCode()  //这是复写hashcode方法,原本是通过hash算法得出不同的hash值,现在为了保证哈希地址值一致,统一返回一个数,可以是任意的
  2.     {
  3.          return 60;
  4.      }
  5.     public boolean equals(Object obj)  //这是复写equals方法,用传入person类作为参数作为一个例子
  6.     {
  7.          if(!(obj instanceof Person))  //先判断一下传进来的参数是否为Person类的对象,是的话才能判断
  8.               return false;
  9.          Person p = (Person)obj;  //多态的局限性,object类里并没有person的属性,需要强转为person类型
  10.          return this.name.equals(p.name);  //比较一下字符串是否相同,并返回
  11.      }
复制代码

评分

参与人数 1技术分 +1 收起 理由
czwanglei + 1

查看全部评分

回复 使用道具 举报
  1. 1、HashSet如何添加元素
  2.          当向一个HashSet集合添加元素的时候,HashSet会调用对象的hashCode()方法来得到哈希值,然后根据HashCode值决定该对象在HashSet中的存储位置,如果

  3.         对应哈希值的内存中没有元素,则添加成功;如果对应的哈希值得内存中有了元素,则调用对象的equals方法和内存中元素比较,如果一样,就不无法添加;

  4.         如果不一样,则也能添加成功(只是在这个内存中,两个元素以链表的形式组织),当然如果相同的对象他们的哈希值不同,也能把元素添加进去

  5. [java] view plaincopyprint?import java.util.*;  
  6. import java.util.*;  
  7. class A  
  8. {  
  9.     //模拟哈希值相同,对象元素相同情况   
  10.     private String name;  
  11.     A(String name){this.name=name;}  
  12.     public int hashCode()  
  13.     {  
  14.         return name.hashCode();  
  15.     }  
  16.     public boolean equals(Object o)  
  17.     {  
  18.         A p=(A)o;  
  19.        return p.name.equals(name);  
  20.     }  
  21.     public String toString()  
  22.     {  
  23.         return name;  
  24.     }  
  25. }  
  26. class B  
  27. {  
  28.     //模拟哈希值相同,对象元素不同的情况   
  29.     private String name;  
  30.     B(String name){this.name=name;}  
  31.     public int hashCode()  
  32.     {  
  33.         return 1;  
  34.     }  
  35.     public boolean equals(Object o)  
  36.     {   
  37.        B p=(B)o;  
  38.        return false;  
  39.     }  
  40.     public String toString()  
  41.     {  
  42.         return name;  
  43.     }  
  44. }  
  45. class C  
  46. {  
  47.     //模拟哈希值不同,但对象元素相同的情况   
  48.     private String name;  
  49.     boolean b=false;  
  50.     C(String name){this.name=name;}  
  51.     public int hashCode()  
  52.     {  
  53.         if(b==false)  
  54.         {  
  55.           b=true;  
  56.           return 1;  
  57.         }  
  58.         else  
  59.             return 3;  
  60.     }  
  61.     public boolean equals(Object o)  
  62.     {  
  63.         return true;  
  64.     }  
  65.     public String toString()  
  66.     {  
  67.         return name;  
  68.     }  
  69. }  
  70. public class SetDemo  
  71. {  
  72.     public static void main(String[]agrs)  
  73.     {  
  74.          
  75.         //哈希值相同,但元素相同无法插入无语   
  76.         HashSet book1=new HashSet();  
  77.         book1.add(new A("xiaocai"));  
  78.         book1.add(new A("xiaocai"));  
  79.         System.out.println(book1);  
  80.         
  81.         //当哈希值相同,但元素比较不同,仍可以插入集合   
  82.         HashSet book2=new HashSet();  
  83.         book2.add(new B("xiaocui"));  
  84.         book2.add(new B("xiaocui"));  
  85.         System.out.println(book2);  
  86.   
  87.         //虽然哈希值不同,当元素相同,仍然可以插入集合   
  88.         HashSet book3=new HashSet();  
  89.         book3.add(new B("xiaosun"));  
  90.         book3.add(new B("xiaosun"));  
  91.         System.out.println(book3);  
  92.     }  
  93. }  
  94. import java.util.*;
  95. import java.util.*;
  96. class A
  97. {
  98.         //模拟哈希值相同,对象元素相同情况
  99.         private String name;
  100.         A(String name){this.name=name;}
  101.     public int hashCode()
  102.         {
  103.                 return name.hashCode();
  104.         }
  105.         public boolean equals(Object o)
  106.         {
  107.         A p=(A)o;
  108.            return p.name.equals(name);
  109.         }
  110.         public String toString()
  111.         {
  112.         return name;
  113.         }
  114. }
  115. class B
  116. {
  117.         //模拟哈希值相同,对象元素不同的情况
  118.         private String name;
  119.         B(String name){this.name=name;}
  120.     public int hashCode()
  121.         {
  122.                 return 1;
  123.         }
  124.         public boolean equals(Object o)
  125.         {  
  126.        B p=(B)o;
  127.            return false;
  128.         }
  129.     public String toString()
  130.         {
  131.         return name;
  132.         }
  133. }
  134. class C
  135. {
  136.         //模拟哈希值不同,但对象元素相同的情况
  137.         private String name;
  138.         boolean b=false;
  139.         C(String name){this.name=name;}
  140.         public int hashCode()
  141.         {
  142.                 if(b==false)
  143.                 {
  144.                   b=true;
  145.                   return 1;
  146.                 }
  147.                 else
  148.                         return 3;
  149.         }
  150.         public boolean equals(Object o)
  151.         {
  152.                 return true;
  153.         }
  154.     public String toString()
  155.         {
  156.         return name;
  157.         }
  158. }
  159. public class SetDemo
  160. {
  161.         public static void main(String[]agrs)
  162.         {
  163.                
  164.                 //哈希值相同,但元素相同无法插入无语
  165.         HashSet book1=new HashSet();
  166.         book1.add(new A("xiaocai"));
  167.         book1.add(new A("xiaocai"));
  168.                 System.out.println(book1);
  169.       
  170.                 //当哈希值相同,但元素比较不同,仍可以插入集合
  171.                 HashSet book2=new HashSet();
  172.         book2.add(new B("xiaocui"));
  173.         book2.add(new B("xiaocui"));
  174.                 System.out.println(book2);

  175.                 //虽然哈希值不同,当元素相同,仍然可以插入集合
  176.         HashSet book3=new HashSet();
  177.         book3.add(new B("xiaosun"));
  178.         book3.add(new B("xiaosun"));
  179.                 System.out.println(book3);
  180.         }
  181. }   当然我们更希望的是HashSet集合中的每个对应的哈希值中只存放一个元素,因此我们就必须正确重写对象的hashCode和equals方法,通常我们尽量保证两个对象通过equals()方法比较返回true时,他们的hashCode()方法返回值也相等      

复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马