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了(當然現在也是,因為name是String)
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

總結:在scala中,== 默認比較內存地址,但如果重寫了equals,則調用該類型重寫的equals進行比較(前提是兩個對象均不為null,否則仍然比較的是地址)

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM