Java編程中的equals辦法應用全解。本站提示廣大學習愛好者:(Java編程中的equals辦法應用全解)文章只能為提供參考,不一定能成為您想要的結果。以下是Java編程中的equals辦法應用全解正文
經由過程上面的例子控制equals的用法
package cn.galc.test; public class TestEquals { public static void main(String[] args) { /** * 這裡應用結構辦法Cat()在堆內存外面new出了兩只貓, * 這兩只貓的color,weight,height都是一樣的, * 但c1和c2卻永久不會相等,這是由於c1和c2分離為堆內存外面兩只貓的援用對象, * 外面裝著可以找到這兩只貓的地址,但因為兩只貓在堆內存外面存儲在兩個分歧的空間外面, * 所以c1和c2分離裝著分歧的地址,是以c1和c2永久不會相等。 */ Cat c1 = new Cat(1, 1, 1); Cat c2 = new Cat(1, 1, 1); System.out.println("c1==c2的成果是:"+(c1==c2));//false System.out.println("c1.equals(c2)的成果是:"+c1.equals(c2));//false } } class Cat { int color, weight, height; public Cat(int color, int weight, int height) { this.color = color; this.weight = weight; this.height = height; } }
畫出內存剖析圖剖析c1和c2比擬的成果
法式:
Cat c1 = new Cat(1,1,1); Cat c2 = new Cat(1,1,1);
履行完以後內存當中的結構以下圖所示,
c1指向一個對象,c2也指向一個對象,c1和c2外面裝著的是這兩只Cat對象在堆內存外面存儲的地址,因為這兩只Cat對象分離位於分歧的存儲空間,是以c1和c2外面裝著的地址確定不相等,是以c1和c2這兩個援用對象也確定不相等。是以履行:“System.out.println(c1==c2);”打印出來的成果確定是false。是以你new出來了兩個對象,你寧神,這兩個對象的援用永久紛歧樣,一樣的話就會把個中一個給籠罩失落了,這個可不成。c1是否是等於c2比擬的是c1和c2這兩個援用外面裝著的內容,由於new出來的兩個對象的它們的援用永久紛歧樣,是以c1和c2這兩個援用的內容也永久紛歧樣,是以c1永久弗成能等於c2。是以經由過程比擬兩個對象的援用是永久沒法使得兩個對象相等的,如出一轍的。
要想斷定兩個對象能否相等,不克不及經由過程比擬兩個對象的援用能否相等,這是永久都得不到相等的成果的,由於兩個對象的援用永久不會相等,所以准確的比擬辦法是直接比擬這兩個對象,比擬這兩個對象的本質是否是一樣的,即這兩個對象外面的內容是否是雷同的,經由過程比擬這兩個對象的屬性值能否雷同而決議這兩個對象能否相等。
Object類供給了一個equals()辦法來比擬兩個對象的內容能否雷同,是以我們可以采取這個辦法去比擬兩個對象能否在邏輯上“相等”。如:c1.equals(c2);這裡是挪用從Object類繼續上去的equals()辦法,經由過程查閱API文檔獲得Object類裡的equals辦法的界說以下:
public boolean equals(Object obj)
在Object這個類外面供給的Equals()辦法默許的完成是比擬以後對象的援用和你要比擬的誰人援用它們指向的能否是統一個對象,即和“c1==c2”這類寫法是一樣的,“c1.equals(c2)”與“c1==c2”是完整等價的。是以直接應用繼續上去的equals()辦法也是沒法直接比擬兩個對象的內容能否雷同的,為此,我們必需得重寫equals()辦法,轉變這個辦法默許的完成。
上面在Cat類外面重寫這個繼續上去的equals()辦法:
class Cat { int color, weight, height; public Cat(int color, int weight, int height) { this.color = color; this.weight = weight; this.height = height; } /** * 這裡是重寫相等從Object類繼續上去的equals()辦法,轉變這個辦法默許的完成, * 經由過程我們本身界說的完成來斷定決議兩個對象在邏輯上能否相等。 * 這裡我們界說假如兩只貓的color,weight,height都雷同, * 那末我們就以為這兩只貓在邏輯上是如出一轍的,即這兩只貓是“相等”的。 */ public boolean equals(Object obj){ if (obj==null){ return false; } else{ /** * instanceof是對象運算符。 * 對象運算符用來測定一個對象能否屬於某個指定類或指定的子類的實例。 * 對象運算符是一個組合單詞instanceof。 * 該運算符是一個雙目運算符,其右邊的表達式是一個對象,左邊的表達式是一個類, * 假如右邊的對象是左邊的類創立的對象,則運算成果為true,不然為false。 */ if (obj instanceof Cat){ Cat c = (Cat)obj; if (c.color==this.color && c.weight==this.weight && c.height==this.height){ return true; } } } return false; } }
此時在再main辦法外面履行打印的敕令:
public static void main(String[] args) { /** * 這裡應用結構辦法Cat()在堆內存外面new出了兩只貓, * 這兩只貓的color,weight,height都是一樣的, * 但c1和c2卻永久不會相等,這是由於c1和c2分離為堆內存外面兩只貓的援用對象, * 外面裝著可以找到這兩只貓的地址,但因為兩只貓在堆內存外面存儲在兩個分歧的空間外面, * 所以c1和c2分離裝著分歧的地址,是以c1和c2永久不會相等。 */ Cat c1 = new Cat(1, 1, 1); Cat c2 = new Cat(1, 1, 1); System.out.println("c1==c2的成果是:"+(c1==c2));//false System.out.println("c1.equals(c2)的成果是:"+c1.equals(c2));//true }
這一次獲得的成果就與前次沒有重寫equals()辦法時獲得的成果就紛歧樣了:
“System.out.println(c1 == c2);”打印出來的成果仍然是false,由於這裡是比擬兩個對象的援用外面的內容,這兩個援用外面的內容固然不相等,並且永久不會相等,所以打印出來的成果確定是false。
“System.out.println(c1.equals(c2));”打印出來的成果為true,由於我們在Cat類外面重寫了equals()辦法,轉變了這個辦法默許的完成,我們把辦法的完成改成只需這個兩個對象是真的存在,而且都是貓,而且它們的色彩(color),身高(height)和體重(weight)都雷同,那末這兩只貓在邏輯上就是如出一轍的,是完整雷同的兩只貓,即這兩只貓是“相等”的。所以這裡打印出來的成果是true。
那末若何比擬兩個字符串對象能否相等?
看上面的例子:
public class TestEquals { public static void main(String args[]){ String s1 = new String("hello"); String s2 = new String("hello"); System.out.println("s1 == s2的成果是:"+(s1 == s2));//false System.out.println("s1.equals(s2)的成果是:"+s1.equals(s2));//true } }
這一次是比擬兩個字符串對象能否相等:
System.out.println(s1 == s2);
打印出來的成果仍然是fase,由於這裡比擬的是s1和s2兩個字符串對象的援用,兩個對象的援用永久不會相等,所以打印出來的成果為false。
System.out.println(s1.equals(s2));
打印出來的成果為true,由於在String類外面重寫了從Object類繼續(一切的類都是從Object類繼續上去,String類固然也不破例,從父類繼續上去就具有了父類的一切屬性與辦法,所以Sting類外面也有equals()辦法,而且還把這個繼續上去的equals()辦法重寫了)上去的equals()辦法,轉變了這個辦法默許的完成,
在String類外面是如許重寫equals()辦法的完成的:用以後的這個字符串對象和指定的字符串對象比擬,指定的字符串對象不克不及為空而且這個對象的字符序列和以後這個字符串對象的字符串序列一樣,假如這些前提都知足,那末這兩個字符串對象就是相等的。
是以這裡的s2曾經知足了前提,所以打印出來的成果是true。
今後在某一個類外面比擬兩個對象能否相等時,起首去API文檔外面查找這個類能否重寫了從Object類繼續上去的equals()辦法。假如重寫了equals()辦法,那末在比擬兩個對象能否相等時挪用的就是重寫今後的equals()辦法,假如沒有重寫,那末挪用時就是直接挪用從Object類外面的繼續上去的誰人equals()辦法,而且采取equals()辦法默許的完成去比擬兩個對象能否相等。是以每個類都可以依據須要對從Object類繼續上去的equals()辦法停止重寫。
關於在API文檔外面找某個類,假如一個類不消引入包便可以直接應用,那末這個類確定是在java.lang這個包外面,如這裡的String類,直接便可以應用了,所以String類必定是在java.lang這個包外面。應用某個類時看這個類引入的是哪一個包,然後就去這個包外面找這個類,不消引入包的類必定是位於java.lang外面,直接去java.lang外面找便可以了。
普通我們在設計一個類時,須要重寫父類的equals辦法,在重寫這個辦法時,須要依照以下幾個規矩設計:
1、自反性:對隨意率性援用值X,x.equals(x)的前往值必定為true.
2、對稱性:關於任何援用值x,y,當且僅當y.equals(x)前往值為true時,x.equals(y)的前往值必定為true;
3、傳遞性:假如x.equals(y)=true, y.equals(z)=true,則x.equals(z)=true
4、分歧性:假如介入比擬的對象沒任何轉變,則對象比擬的成果也不該該有任何轉變
5、非空性:任何非空的援用值X,x.equals(null)的前往值必定為false
例如:
public class People { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; People other = (People) obj; if (age != other.age) return false; if (firstName == null) { if (other.firstName != null) return false; } else if (!firstName.equals(other.firstName)) return false; if (lastName == null) { if (other.lastName != null) return false; } else if (!lastName.equals(other.lastName)) return false; return true; } }
在這個例子中,我們劃定一小我,假如姓、名和年紀雷同,則就是統一小我。固然你也能夠再增長其他屬性,好比必需身份證號雷同,能力剖斷為統一小我,則你可以在equals辦法中增長對身份證號的斷定!
總結:比擬兩個對象能否相等,我們采取equals()辦法,斷定兩個對象能否相等的前提是由我們重寫equals()辦法的完成後界說的,如許便可以比擬靈巧地應用equals()辦法在分歧的類外面比擬位於統一類下的兩個對象能否相等了。