前言
首先再次強調hashcode (==)和equals的真正含義(我記得以前有人會說,equals是判斷對象內容,hashcode是判斷是否相等之類):
equals:是否同一個對象實例。注意,是“實例”。比如String s = new String("test"); s.equals(s), 這就是同一個對象實例的比較;
等號(==):對比對象實例的內存地址(也即對象實例的ID),來判斷是否是同一對象實例;又可以說是判斷對象實例是否物理相等;
Hashcode:我覺得可以這樣理解:並不是對象的內存地址,而是利用hash算法,對對象實例的一種描述符(或者說對象存儲位置的hash算法映射)——對象實例的哈希碼。
按照約定,equals要滿足以下規則:自反性: x.equals(x) 一定是true對null: x.equals(null) 一定是false
對稱性: x.equals(y) 和 y.equals(x)結果一致
傳遞性: a 和 b equals , b 和 c equals,那么 a 和 c也一定equals。
一致性: 在某個運行時期間,2個對象的狀態的改變不會不影響equals的決策結果,那么,在這個運行時期間,無論調用多少次equals,都返回相同的結果。
一、== 和 equals的區別:
==主要是兩個變量值的比較,返回值為true 或者是false。對於普通變量,如:int a=10; int b= 10; a==b,返回為 true。
而對於下面情況:
String a=new String("abc");
String b=new String("abc");
String c=a
String d="abc";
String f="abc";
a==b; 返回的則是一個false。這是因為,對於對象的比較是對對象引用的比較,對於a和b ,他們在內存中對應的地址是不一樣的
c==a 返回的值是一個true,c引用了a,內存地址一樣的
d==f 返回的值是一個ture,因為 d,f 在編譯期放進了字符串常量池中,d,f都引用了字符串池的“abc”
a==f 返回的值是一個false,a和f引用的內存地址不一樣
==操作符並不涉及對象內容的比較。若要對對象內容進行比較,則用equals. 如果 在本例中,a.equals(b)則返回是一個true值。
總而言之:==是對對象地址的比較,而equals是對對象內容的比較。對於基本數據類型,一般用==,而對於字符串的比較,一般用equals
二、對於compareTo(), 在API中,Java.lang包下面的基本數據類型的封裝類都提供了該方法,如 Integer,Float,Byte,Short,Character 等
compareTo()的返回值是int,它是先比較對應字符的大小(ASCII碼順序)
1、如果字符串相等返回值0
2、如果第一個字符和參數的第一個字符不等,結束比較,返回他們之間的差值(ascii碼值)(負值前字符串的值小於后字符串,正值前字符串大於后字符串)
3、如果第一個字符和參數的第一個字符相等,則以第二個字符和參數的第二個字符做比較,以此類推,直至比較的字符或被比較的字符有一方全比較完,這時就比較字符的長度.
例:
String s1 = "abc";
String s2 = "abcd";
String s3 = "abcdfg";
String s4 = "1bcdfg";
String s5 = "cdfg";
System.out.println( s1.compareTo(s2) ); // -1 (前面相等,s1長度小1)
System.out.println( s1.compareTo(s3) ); // -3 (前面相等,s1長度小3)
System.out.println( s1.compareTo(s4) ); // 48 ("a"的ASCII碼是97,"1"的的ASCII碼是49,所以返回48)
System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII碼是97,"c"的ASCII碼是99,所以返回-2)