很多時候,設計一個類,我們需要重寫超類Object中的equals(Object o)、hashCode()以及toString() - equals(Object o):比較目前對象與指定對象o的狀态(比較兩個對象中所有字段的值)是否相同,是即傳回true,否則傳回false
- hashCode():獲得目前對象的散列碼,超類Object中定義的hashCode()會将對象的存儲位址作為散列碼傳回
- toString():為友善操作而存在,可用于列印對象的狀态資訊
那麼,它們三兒具體應該怎麼搞呢?
一、User類
定義一個用于測試的類User,包含兩個字段以及對應的get/set方法 - - age:使用者年齡,int類型
- - name:使用者名字,String類型
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
二、重寫equals(Object o)
設計步驟: - 1. 用“==”判斷對象o與目前對象是否為同一個對象,若是則直接傳回true
- 2. 若對象o為null,則直接傳回false
- 3. 根據情況選擇使用getClass()方法或instanceOf關鍵字來判斷對象o與目前對象是否為同一類型,若不是則傳回false
- 4. 使用強制類型轉換将對象o轉化為目前對象類型
- 5. 依次判斷對象o與目前對象中的所有對應字段是否相同,若全部相同則傳回true
代碼:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public boolean equals(Object o) {
if(this==o)return true;//1、用“==”判斷對象o與目前對象是否為同一個對象,若是則直接傳回true
if(o==null)return false;//2、 若對象o為null,則直接傳回false
if(!(getClass()==o.getClass()))return false;//3、使用getClass()方法來判斷對象o與目前對象是否為同一類型,若不是則傳回false
User user=(User)o;//4、使用強制類型轉換将對象o轉化為目前對象類型User
return user.getAge()==age&&Objects.equals(name,user.getName());//5、依次判斷對象o與目前對象中的所有對應字段是否相同,若全部相同則傳回true
}
}
三、重寫hashCode()
設計步驟: - 1. 隻要重寫了equals()方法,則必須重寫hashCode()
- 2. 當a.equals(b)傳回true時,a.hashCode()==b.hashCode()也必須傳回true
- 3. 一般直接将所有字段對應的散列碼相加即可
- 4. 多數情況下會添加一個素數31,用于最大可能的保證散列碼的唯一;當然31也可以換成7,11,13等(但一定是素數)。大多數人喜歡用31是因為hash*31可以被虛拟機優化為(hash<<5)-hash
代碼:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public int hashCode() {
int hash=0;
int
hash=31*hash+Integer.hashCode(age);//31也可以換成7,11,13等(但一定是素數)。大多數人喜歡用31是因為hash*31可以被虛拟機優化為(hash<<5)-hash
hash=31*hash+Objects.hashCode(name);
return hash;
}
}
四、重寫toString
toString()的設計就很簡單了,一般都是自定義的格式。下面是java核心思想中推薦的格式來重寫的toString():
代碼:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public String toString() {
return getClass().getName()+
"[name is:"+getName()+
",age is:"+getAge()+
"]";
}
}