众所周知,Java比较对象相等的equals方法比较的是== 比较的是引用,因此很多时候下面的两个声明


val c1=new Person("Postbird",12);
val c2=new Person("Postbird",12);

c1 == c2 有时候 结果是不相等的,因为new 出来的引用在堆上的地址不相等,而重写equals方法也是经常做的事情

事实上,使用Scala后,很少重写equals和hashcode方法,因为在Scala的case类中,equals和hashcode是自动创建的,提供了很大的方便。

如果需要使用对象测试相等性或者是调用hashcode作为Map键,应该用case类。

需要注意的是Scala的==与java是不同的,比较的也是值的向同性,而不是引用

下面是Scala测试相等的方法:

1、equals方法


val p1=Person("postbird",11);

val p2=Person("Postbird",11);

val p3=Person("Postbird",20);

//注意 这里没有使用new 因为Person是case类,可以省略new关键字

Scala的equals方法和java相同同,比较的是在堆上的引用的地址,因此使用java调用的p1.equals(p2) 结果是true,而使用scala,p1 equals p2 结果也是true

因此Scala的equals方法用于测试的相等,也就是说因为p1和p2有相同的值,因此 p1 equals p2 的结果为true,p1和p2不需要指向同一个实例。

当然 p1 equals p3 的结果肯定是false。

2、==方法

== 相信很多人都熟悉 == 在if中用的最多的就是这个,在Scala中 == 是一个方法,用来代表equals,因此 == 的行为和equals完全一样,也就是只测试值是否相等。

在java、C++、C#中  == 测试的是引用,而不是值。

Scala中 == 测试值的相等,与equals相似。

当然 null在 == 左边比较特殊。

与上面的实例比较:


p1 == p2  //true

p1 == p3  //false

p1==null //false

null==p1 //false

null==null //true

值得注意的是null==null,编译会产生警告,这永远为 true

3、!=方法

!= 方法可以类比 == 方法,表示不相等。


p1 != p2 //false

p1 != p3 //true

4、eq和ne方法

scala中eq方法用于测试引用的相等性。

因此


p1 eq p1//true

p1 eq p2 //false

当然  null eq null 编译的时候也会给出警告。

scala的eq方法如同java、c++、c#中的==操作符。

ne方法是eq的反方法。

5、数组相等和sameElements方法

比较两个数组,scala中 Array(1,2)==Array(1,2) 结果出乎意料 是false。

可能让人无法接受,当然scala给出了简单的解决方案,sameElements方法。

因此   Array(1,2) sameElements Array(1,2)  的结果是 true

Scala的数组Array是可变的原始Java数组,因此和Scala库中我们习惯使用的集合类型有不同的方法。

如果试图比较数组,考虑使用序列更好,Scala的各种序列真的是不错的Array替代方案,当然,不得已只能使用Array也没办法。

和数组不一样 , 序列(比如list)的相等性行为就符合期望。


List(1,2) == List(1,2)    //true

List(1,2) sameElement List(1,2)   //true