1. 程式人生 > >scala 判斷物件相等/equals

scala 判斷物件相等/equals

 1 package scala_enhance.scalaextends
 2 
 3 import scala.collection.mutable.HashMap
 4 
 5 /**
 6  * scala中判斷物件相等
 7  * 原則:
 8  * 如果兩個物件相等,那麼其hashcode必定相同,所以重寫equals方法,要重寫hashcode(預設情況下hashcode是根據記憶體地址計算出來的值)
 9  * 但如果hashcode相同(即使用 == 比較為true),卻不能證明他們相等
10  * 關於重寫equals為什麼需要重寫hashCode請參考https://www.cnblogs.com/wang-meng/p/7501378.html
11 * 12 * 對於基本資料型別,== 在java和scala中均比較的是兩個變數的值。 13 * 14 * 在scala中,對於引用物件,如果有一個物件為null,== 呼叫的是eq(比較物件的記憶體地址),如果均不為null,則呼叫equals, 15 * 注意這個equals是呼叫java中的equals,所以預設比較的還是記憶體地址,綜上 == 預設情況下在scala中依然比較的是記憶體地址 16 * 此外scala中的String就是java中的String,所以在scala中,如對"ok" == "ok",呼叫的是java String的equals 17 *
18 * 而在java中,== 永遠比較的是記憶體地址,與你是否重寫該物件的equals無關 19 * 20 */ 21 22 class Student(val name:String) { 23 val age = 100; 24 25 override def equals(obj:Any):Boolean = { 26 if(!obj.isInstanceOf[Student]) { 27 false; 28 }else { 29 val x = obj.asInstanceOf[Student]; 30 this
.name == x.name; //這個地方也可以使用equals比較,這樣寫的話就是呼叫java String的equals了 31 } 32 } 33 34 35 override def hashCode():Int = { 36 name.length(); 37 } 38 39 40 } 41 42 object Demo2 { 43 44 val s1 = new Student("hello"); 45 val s2 = new Student("hello"); 46 47 48 //重寫equals之前的測試 49 println("ok" == "ok")//true,呼叫的是equals,但由於是String型別,其重寫了equals方法,比較的是值 50 println("ok" == null)//false,呼叫eq,比較的是記憶體地址 51 println(null == null)//true,呼叫eq,比較的是記憶體地址 52 println("ok".equals("ok")); //true 53 54 println(s1 == s2);//false,未重寫equals,比較的地址 55 56 57 //只重寫equals的測試 58 println(s1 == s2); //true,此時呼叫的是重寫後的equals,比較的是name字串是否相同,即呼叫java String的equals,比較的是值 59 println(s1.equals(s2))//true,也是呼叫其內部重寫的equals 60 61 println(s1.eq(s2));//false, eq比較的是地址,而我們還沒有重寫eq方法 62 63 64 /*而在java中, == 只比較記憶體地址 65 String str1 = new String("hello"); 66 String str2 = new String("hello"); 67 System.out.println(s1 == s2);//false 68 */ 69 70 //此時測試hashMap,即s1與s2相同,hashCode卻不同,此時對於HashMap來說s1與s2是兩個不同的物件 71 println(s1.hashCode() == s2.hashCode());//false 72 val map = new HashMap[Student,Int](); 73 map.put(s1,100); 74 map.put(s2,200); 75 println(map.get(s1));//Some(100) 76 println(map.get(s2));//Some(200) 77 78 //重寫hashCode後重新測試,此時對於HashMap來說s1與s2是同一個物件,s2的值會覆蓋s1的值 79 println(map.get(s1));//Some(200) 80 println(map.get(s2));//Some(200) 81 82 83 def main(args: Array[String]): Unit = { 84 85 } 86 }

 關於重寫equals為什麼需要重寫hashCode請參考https://www.cnblogs.com/wang-meng/p/7501378.html

附未重寫時的方法來源,但是很奇怪,java Object中並沒有eq,只有equals