018Java面試001==和equals的區別
阿新 • • 發佈:2021-12-06
本文主要學習了==和equals的區別。
1 ==和equals
1.1 執行程式碼並檢視結果
測試程式碼:
1 public class Demo { 2 public static void main(String[] args) { 3 // String 4 String s1 = new String("abc"); 5 String s2 = new String("abc"); 6 System.out.println(s1 == s2);// false 7 System.out.println(s1.equals(s2));// true 8 // String Set9 Set<String> sset = new HashSet<String>(); 10 sset.add(s1); 11 sset.add(s2); 12 System.out.println(sset.size());// 1 13 // Person 14 Person p1 = new Person("abc"); 15 Person p2 = new Person("abc"); 16 System.out.println(p1 == p2);// false 17 System.out.println(p1.equals(p2));//false 18 // Person Set 19 Set<Person> pset = new HashSet<Person>(); 20 pset.add(p1); 21 pset.add(p2); 22 System.out.println(pset.size());// 2 23 } 24 } 25 26 class Person { 27 String name; 28 public Person(String name) { 29 super(); 30 this.name = name;31 } 32 }
1.2 ==和equals的區別
1)==既可以比較基本型別也可以比較引用型別。對於基本型別就是比較值,對於引用型別就是比較記憶體地址。
2)equals方法屬於java.lang.Object類裡面的方法,如果該方法沒有被重寫過,那麼預設通過==判斷。String類的equals方法是被重寫過的,所以形成了equals方法是比較值的錯誤觀點。
3)使用equals比較兩個物件,具體要看兩個物件所在的類有沒有重寫hashCode方法和equals方法。
2 重寫hashCode和equals
當一個類有自己特有的“邏輯相等”概念的時候,比如通過類的某某屬性判斷是否是同一個物件,就需要重寫equals方法。
當改寫equals方法的時候,總是要改寫hashCode方法的。否則,根據equals方法判斷相等的兩個物件,在根據hashCode方法判斷的時候,呼叫的還是Object類的hashCode方法,就會得到兩個物件不等的結果。那麼在使用hashCode方法判斷兩個物件是否相等的環境中,比如HashSet和HashMap等,就會認為是兩個物件。所以,複寫equals方法的時候一般都需要同時複寫hashCode方法。
3 重寫hashCode使用31這個數字
在使用Eclipse的時候,可以自動重寫equals方法和hashCode方法,檢視重寫的hashCode方法時,會發現使用了31這個數字:
1 @Override 2 public int hashCode() { 3 final int prime = 31; 4 int result = 1; 5 result = prime * result + ((name == null) ? 0 : name.hashCode()); 6 return result; 7 }
原因如下:
1)31是質數。hashCode方法要求產生hash值的衝突概率最小,質數的特性(只有1和自己是因子)能夠使得它和其他數相乘後得到的結果比其他方式更容易產成唯一性。
2)31比32少1,數字和31的乘法可以被編譯器優化為將該數字左移五位後再減去該數字,有較高的效能(計算機的乘法涉及到移位計算)。
虛擬機器的優化邏輯:
1 5 * 31 = 5[101] * 32 - 5[101] 2 = 10100000 - 101 = 10011011 3 = 155