高卒文系Scala vol.14 - オブジェクトの等価性 -

Scala本、5.7辺りそのまんまを書きます。

Javaではオブジェクトの比較をする時に、「==」演算子を使うか「equals」メソッドを使うかで結果が違う場合があります。

特に、頻繁に利用されるjava.lang.Stringの比較時。

「==」の参照同一性の判定に対し、「equals」は文字列の同値性を判定します。

これが曲者で、「==」を使った場合、JVMが対象文字列が既にキャッシュしている状態とまだキャッシュされてない状態で

実行結果が変わる可能性があります。

Javaではオブジェクトの比較は「equals」でするのが基本中の基本なのですが、初心者が出すバグの一つかな、と思ったり。

Scalaの場合、「==」はもちろんメソッドで、内部で「equals」メソッドを呼んでます。

なので、「==」も「equals」も結果は同じです。

参照同一性の判定をしたい場合は、「eq」メソッドを使います。

逆に、参照の非同一性を判定したい場合は、「ne」メソッドを使います。

val t1 = ("zetta" ,"1985")
val t2 = ("zetta", "1985")
println(t1 == t2)
println(t1 equals t2)
println(t1 eq t2)
println(t1 ne t2)
true
true
false
true

ここで、Stringの代わりにpairのtupleを例に出したのは、tupleインスタンスはキャッシュされないからです。

僕の環境だと、JVMがStringインスタンスをキャッシュして、二つの変数が同じインスタンスを指し示してしまうので、

「eq」メソッドで比較した場合、trueが返ってきます。

val s1 = "zetta1985"
val s2 = "zetta1985"
println(s1 == s2)
println(s1 equals s2)
println(s1 eq s2)
println(s1 ne s2)
true
true
true
false

Scalaでは、Javaのように「プリミティブは==、オブジェクトはequalsで比較する」、では無く、

「==」メソッドを用いて、データの比較をするのが基本になりそうですねー

このエントリーをはてなブックマークに追加
comments powered by Disqus