• 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

  • 相关阅读:
    万能五笔的广告怎么去掉
    JS版日期格式化和解析工具类,毫秒级
    Toast信息提示:下拉收起(基于jQuery)(app信息提示更新)
    MUI右滑关闭窗口用Webview的drag实现
    mui 列表项左右滑删除功能升级(仿微信左滑 点击删除后出现确认删除)
    修正 Mui 下拉上拉刷新功能
    javascript中new Date()的浏览器兼容性问题
    Mui 下拉刷新,刷新完成功能实现
    mysql 时间类型精确到毫秒、微秒及其处理
    Windows 上如何安装Sqlite
  • 原文地址:https://www.cnblogs.com/tele-share/p/10128804.html
Copyright © 2020-2023  润新知