Scala中==、eq与equals的区别

推荐先了解一下hashCode、identityHashCode、equals和==的原理,再来看Scala中==、eq与equals的区别

根据官方API的定义:

  • final def ==(arg0: Any): Boolean
    The expression x == that is equivalent to if (x eq null) that eq null else x.equals(that).
  • final def eq(arg0: AnyRef): Boolean
    Tests whether the argument (that) is a reference to the receiver object (this).
  • def equals(arg0: Any): Boolean
    The equality method for reference types.

简言之,equals方法是检查值是否相等,而eq方法检查的是引用是否相等。

对于==来说,所以如果比较的对象是null,那么==调用的是eq,不是null则调用的是equals。

示例1

1
2
3
4
5
6
7
val c=new String("aa");
val d=new String("aa");

println(c,d) //(aa,aa)
println(c==d) //true
println(c.equals(d)) //true
println(c.eq(d)) //false

可以看出,对于不是null的对象,==和equals是一样的,这一点和java不同,java中的==对于引用类型来说,比较永远是两个对象的内存地址是否相等。

在Java中如果要对两个对象进行值比较,那么必须要实现equals 和hashCode方法。而在scala中为开发者提供了case class,默认实现了equals 和hashCode方法。

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
object T2 {

def main(args: Array[String]): Unit = {
//普通类
val a1=new A(1,"abc")
val a2=new A(1,"abc")
println(a1==a2) //false
println(a1.equals(a2))//false
println(a1.eq(a2))//false

//样例类
val b1=new B(2,"efg")
val b2=new B(2,"efg")
println(b1==b2) //true
println(b1.equals(b2))//true
println(b1.eq(b2))//false
}
}
//普通类
class A(_a:Int,_b:String){
var a:Int=_a
var b:String=_b
}
//样例类
case class B(_a:Int,_b:String){
var a:Int=_a
var b:String=_b
}

可以看到,对于样例类,默认实现了equals 和hashCode,所以==equals都是true,而eq比较的永远都是内存地址是否相等,所以输出false。

【参考资料】

Scala中==,eq与equals的区别