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.htmlhtml
总结:在scala中,== 默认比较内存地址,但若是重写了equals,则调用该类型重写的equals进行比较(前提是两个对象均不为null,不然仍然比较的是地址)java
附未重写时的方法来源,可是很奇怪,java Object中并无eq,只有equalside