問題一:我們自定義類中的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()方法較爲簡單,不多說了……