天天看點

重寫equals()&hashCode()&toString()—Java類設計

很多時候,設計一個類,我們需要重寫超類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()+
			"]";
	}
}

           

繼續閱讀