java hashcode和equal总结

ashCode和equal两个方法都是Object基类定义实现的方法。hashCode即哈希码,就是获取对象对应的hash值的函数;equal即相等,就是判断两个对象是否相等的函数。为什么Object对象会有这两个方法呢,equal方法好理解,用来比较两个对象是否相等,但是hashCode有什么用呢?

先看下面一段代码,Person类没有重写这两个方法,继承了Object类的方法,我们来看看Object类中定义的这两个方法是如何实现的。

 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.basic.equal;  
  2.   
  3. public class BasicEqual {  
  4.     public static void main(String argv[]) {  
  5.         Person p1 = new Person("lee""changsha","123");  
  6.         Person p2 = new Person("lee""changsha","123");  
  7.           
  8.         System.out.println(p1 + " " + p1.hashCode());  
  9.         System.out.println(p2 + " " + p2.hashCode());  
  10.           
  11.         System.out.println(p1.equals(p2));  
  12.     }  
  13. }  
  14.   
  15. class Person {  
  16.     private String name;  
  17.     private String address;  
  18.     private String number;  
  19.       
  20.     public Person(String name, String address, String number) {  
  21.         this.address = address;  
  22.         this.name = name;  
  23.         this.number = number;  
  24.     }  
  25.       
  26.     public String getName() {  
  27.         return name;  
  28.     }  
  29.     public void setName(String name) {  
  30.         this.name = name;  
  31.     }  
  32.     public String getAddress() {  
  33.         return address;  
  34.     }  
  35.     public void setAddress(String address) {  
  36.         this.address = address;  
  37.     }  
  38.     public String getNumber() {  
  39.         return number;  
  40.     }  
  41.     public void setNumber(String number) {  
  42.         this.number = number;  
  43.     }  
  44. }  

运行结果如下:

 

 

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. com.basic.equal.Person@3ce53108 1021653256  
  2. com.basic.equal.Person@6af62373 1794515827  
  3. false  

从上面的结果我们可以看出,Object类的HashCode方法其实返回的就是对象的地址,而equal方法不是很清楚,但通过Object类的源码我们知道equal方法比较的是两个对象的地址。

 

下面,我们再看一段代码,Person类没有重写这两个方法,继承了Object类的方法

 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.basic.equal;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Iterator;  
  5.   
  6. public class BasicEqual {  
  7.     public static void main(String argv[]) {  
  8.         Person p1 = new Person("lee""changsha","123");  
  9.         Person p2 = new Person("lee""changsha","123");  
  10.           
  11.         HashSet<Person> set = new HashSet<Person>();  
  12.         set.add(p1);  
  13.         set.add(p2);  
  14.           
  15.         Iterator<Person> it= set.iterator();  
  16.         while(it.hasNext())  
  17.         {  
  18.             Person p = it.next();  
  19.             System.out.println(p + " " + p.getName());  
  20.         }   
  21.     }  
  22. }  
  23.   
  24. class Person {  
  25.     private String name;  
  26.     private String address;  
  27.     private String number;  
  28.       
  29.     public Person(String name, String address, String number) {  
  30.         this.address = address;  
  31.         this.name = name;  
  32.         this.number = number;  
  33.     }  
  34.       
  35.     public String getName() {  
  36.         return name;  
  37.     }  
  38.     public void setName(String name) {  
  39.         this.name = name;  
  40.     }  
  41.     public String getAddress() {  
  42.         return address;  
  43.     }  
  44.     public void setAddress(String address) {  
  45.         this.address = address;  
  46.     }  
  47.     public String getNumber() {  
  48.         return number;  
  49.     }  
  50.     public void setNumber(String number) {  
  51.         this.number = number;  
  52.     }  
  53. }  

运行结果如下:

 

 

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. com.basic.equal.Person@6af62373 lee  
  2. com.basic.equal.Person@3ce53108 lee  

Hashset不是说保证添加的对象不重复吗,我们构造的对象明明有相同的名字,地址和电话,为什么HashSet认为p1和p2是不同的对象呢,这个就和HashSet判断对象是否相等的方法相关了,HashSet比较两个对象是否相等的,有两个步骤,1)比较HashCode、2)比较equal。下面我们来验证一下是否是这样的,基于下面的代码:

 

 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.basic.equal;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Iterator;  
  5.   
  6. public class BasicEqual {  
  7.     public static void main(String argv[]) {  
  8.         Person p1 = new Person("lee""changsha","123");  
  9.         Person p2 = new Person("lee""changsha","123");  
  10.           
  11.         HashSet<Person> set = new HashSet<Person>();  
  12.         set.add(p1);  
  13.         set.add(p2);  
  14.           
  15.         Iterator<Person> it= set.iterator();  
  16.         while(it.hasNext())  
  17.         {  
  18.             Person p = it.next();  
  19.             System.out.println(p + " " + p.hashCode() + " " +p.getName());  
  20.         }   
  21.      }  
  22. }  
  23.   
  24. class Person {  
  25.     private String name;  
  26.     private String address;  
  27.     private String number;  
  28.       
  29.     public Person(String name, String address, String number) {  
  30.         this.address = address;  
  31.         this.name = name;  
  32.         this.number = number;  
  33.     }  
  34.       
  35.     @Override  
  36.     public int hashCode() {  
  37.         return 1;  
  38.     }  
  39.       
  40.     @Override  
  41.     public boolean equals(Object obj) {  
  42.         return true;  
  43.     }  
  44.     public String getName() {  
  45.         return name;  
  46.     }  
  47.     public void setName(String name) {  
  48.         this.name = name;  
  49.     }  
  50.     public String getAddress() {  
  51.         return address;  
  52.     }  
  53.     public void setAddress(String address) {  
  54.         this.address = address;  
  55.     }  
  56.     public String getNumber() {  
  57.         return number;  
  58.     }  
  59.     public void setNumber(String number) {  
  60.         this.number = number;  
  61.     }  
  62. }  

 

上面代码的运行结果:

 

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. com.basic.equal.Person@1 1 lee  

我们发现只有一条记录,也就是说hashset认为两个对象是同一个对象,那是因为hashcode值相等了,equal方法返回true了。如果我们让hashcode方法继承object,或者让equal方法继承Object,得到的结果如下:

 

com.basic.equal.Person@1 1 lee

com.basic.equal.Person@1 1 lee

 

从上面的试验我们验证了Hashset比较对象的两个方法。通过上面的例子,我们可以看到,其实HashCode方法我们可以不关心直接让它返回固定值,我们只需要实现我们的equal方法就行了,那HashCode方法是不是就没有用了呢,其实它的作用还是很大的,它的作用就是用来提高效率的,我们之所以选择Hahset或hashmap数据结构就是因为它们的效率,比较对象时先通过hashcode缩小范围,然后再使用equal方法比较是否相等,如果我们都是一个hashcode值,相当于比较一个对象时,就需要和所有的对象使用equal方法比较,这样效率就非常的低。我想现在应该差不多明白这两者之间的关系了,^_^。

 

另外附加hashcode和equals的标准写法:

 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public int hashCode() {  
  3.     final int prime = 31;  
  4.     int result = 1;  
  5.     result = prime * result + ((name == null) ? 0 : name.hashCode());  
  6.     result = prime * result + ((address == null) ? 0 : address.hashCode());  
  7.     result = prime * result + ((number == null) ? 0 : number.hashCode());  
  8.     return result;  
  9. }  
  10.   
  11. @Override  
  12. public boolean equals(Object obj) {  
  13.     if (this == obj) {  
  14.         return true;  
  15.     }  
  16.     if (obj == null) {  
  17.         return false;  
  18.     }  
  19.     if(getClass() != obj.getClass()) {  
  20.         return false;  
  21.     }  
  22.     Person p = (Person)obj;  
  23.       
  24.     if (name == null) {  
  25.         if(p.name != null) {  
  26.             return false;  
  27.         }  
  28.     } else if (!name.equals(p.name)) {  
  29.         return false;  
  30.     }  
  31.       
  32.     if (address == null) {  
  33.         if (p.address != null) {  
  34.             return false;  
  35.         }  
  36.     } else if (!address.equals(p.address)) {  
  37.         return false;  
  38.     }  
  39.       
  40.     if (number == null) {  
  41.         if (p.number != null) {  
  42.             return false;  
  43.         }  
  44.     } else if (!number.equals(p.number)) {  
  45.         return false;  
  46.     }  
  47.       
  48.     return true;  
  49. }  

http://blog.csdn.net/pingnanlee/article/details/17228579

猜你喜欢

转载自oywl2008.iteye.com/blog/2297721