`
zzhblh
  • 浏览: 15108 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

14.JAVA中重写equals()和hashcode()方法

 
阅读更多
1.何时需要重写equals()
当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。
2.当改写equals()的时候,总是要改写hashCode()
根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode方法,它们仅仅是两个对象。因此,违反了“相等的对象必须具有相等的散列码”。

我们应该先了解java判断两个对象是否相等的规则。 在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等

我们必需清楚,当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()和hashCode()方法。



public static void main(String args[]){ 
String s1=new String("zhaoxudong"); 
String s2=new String("zhaoxudong"); 
System.out.println(s1==s2);//false 
System.out.println(s1.equals(s2));//true 
System.out.println(s1.hashCode());//s1.hashcode()等于s2.hashcode() 
System.out.println(s2.hashCode()); 
Set hashset=new HashSet(); 
hashset.add(s1); 
hashset.add(s2); 

Iterator it=hashset.iterator(); 
while(it.hasNext()) 
{ 
System.out.println(it.next()); 
} 

最后在while循环的时候只打印出了一个”zhaoxudong”。
输出结果为:false
true
-967303459
-967303459
这是因为String类已经重写了equals()方法和hashcode()方法,所以在根据上面的第1.2条原则判定时,hashset认为它们是相等的对象,进行了重复添加。
但是看下面的程序:


 
import java.util.*; 
public class HashSetTest 
{ 
public static void main(String[] args) 
{ 
HashSet hs=new HashSet(); 
hs.add(new Student(1,"zhangsan")); 
hs.add(new Student(2,"lisi")); 
hs.add(new Student(3,"wangwu")); 
hs.add(new Student(1,"zhangsan")); 

Iterator it=hs.iterator(); 
while(it.hasNext()) 
{ 
System.out.println(it.next()); 
} 
} 
} 
class Student 
{ 
int num; 
String name; 
Student(int num,String name) 
{ 
this.num=num; 
this.name=name; 
} 
public String toString() 
{ 
return num+":"+name; 
} 
} 
输出结果为: 
1:zhangsan 
1:zhangsan 
3:wangwu 
2:lisi 


在Student类中重新hashcode()和equals()方法后


class Student 
{ 
int num; 
String name; 
Student(int num,String name) 
{ 
this.num=num; 
this.name=name; 
} 
public int hashCode() 
{ 
return num*name.hashCode(); 
} 
public boolean equals(Object o) 
{ 
Student s=(Student)o; 
return num==s.num && name.equals(s.name); 
} 
public String toString() 
{ 
return num+":"+name; 
} 
} 


根据重写的方法,即便两次调用了new Student(1,"zhangsan"),我们在获得对象的哈希码时,根据重写的方法hashcode(),获得的哈希码肯定是一样的(这一点应该没有疑问吧)。
当然根据equals()方法我们也可判断是相同的。所以在向hashset集合中添加时把它们当作重复元素看待了。所以运行修改后的程序时,我们会发现运行结果是:
1:zhangsan
3:wangwu
2:lisi
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics