toString、hashCode、equals的重寫原因與重寫示例

2009-02-19 16:03

    問題一:我們自定義類中的toString()、hashCode()和equals(Object obj)均繼承自Object,其中equals()方法是比較兩對象的地址是否相同,hashCode()方法返回的是該對象本身的內存地址。但這個需 求不能滿足我們的需求。如問題二。(JDK中其它類都已重寫了上述方法,不作考慮)

    問題二:在我們往HashSet中添加自定義對象的時候(HashSet中不能添加相同的對象),HashSet會先將已存在的對象與欲添加的對象進行一 一對比,相同的對象不允許再添加。其比較規則爲:如果兩對象的hashCode()方法返回值不一樣,肯定不是相同的對象,可添加;如果 hashCode()一樣,則再判斷equals()返回是否爲真,不爲真則肯定不是相同的對象,可添加,爲真由證明兩對象完全相同,不再添加到 HashSet中。那按Object()中的hashCode()方法,則只要內存不一樣,則兩對象的hashCode就不一樣,則認爲兩對象不相同,可 往HashSet中添加,這違背了我們實際需求。

    結論:我們自定義類如果想往HashSet等集合中添加時,必須重寫equals(Object obj)和hashCode()方法,使相同內容的對象其equals(Object obj)爲真,返回的hashCode()一致。如下:

public class Stu {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
  
   if(!(obj instanceof Stu)){
    return false;
   }
   if(obj==null){
    return false;
   }
   Stu tmp=(Stu)obj;
   if(tmp.age!=this.age && !tmp.name.equals(this.name)){
    return false;
   }
   return true;
}
@Override
public int hashCode() {
   return this.age*this.name.hashCode();
}
public String getName() {
   return name;
}
public void setName(String name) {
   this.name = name;
}
public int getAge() {
   return age;
}
public void setAge(int age) {
   this.age = age;
}
}

測試類:
import java.util.HashSet;
public class Test {
public static void main(String[] args) {
   Stu s1=new Stu();
   s1.setAge(18);
   s1.setName("abc");
   Stu s2=new Stu();
   s2.setAge(18);
   s2.setName("abc");
   System.out.println(s1==s2);
   System.out.println(s1.equals(s2));
   HashSet set=new HashSet();
   set.add(s1);
   set.add(s2);
   System.out.println(set.size());
}
}

在上面的測試中兩對象的年齡與姓名均一致,但其內存地址不一樣。所以用"=="爲假,用equals爲真,返回的set.size()爲1,即往HashSet中只能添加進一個對象。至於toString()方法較爲簡單,不多說了……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章