2012-01-30 46 views
31

##hashCodeの違いは何ですか?`##`と `hashCode`の違いは何ですか?

どちらのクラスにも同じ値が出力されているようですが、私が使用するオーバーロードはhashCodeです。 Googleはシンボル##が見つからないため、助けません。 AnyVal

+1

'1.0 hashCode' v' 1.0 ## 'v' 1 hashCode' v '1 ##' - http://www.scala-lang.org/api/current/ scala/Any.html – Debilski

+3

少ししかありませんが、[SymbolHound](http://www.symbolhound.com/)を使用してそのようなシンボルを検索できます。 –

+0

ああ。したがって、 '' 1.hashCode' '==' '1。##'、 '' 1.2.hashCode' '==' '1.2。##'です。異なった振る舞いをするのは '1.0.hashCode''!= '' 1.0。## 'だけです(したがって、' '## ''は数値の比較に適しています)。 –

答えて

32

「サブクラスは、」適切にハッシュの観点からに動作しません。もちろん

scala> 1.0.hashCode 
res14: Int = 1072693248 

をこれにコールに箱詰めされています

scala> new java.lang.Double(1.0).hashCode 
res16: Int = 1072693248 

私たちがすることを好むかもしれません:

scala> new java.lang.Double(1.0).## 
res17: Int = 1 

scala> 1.0.## 
res15: Int = 1 

int 1もdoubleであることを考慮して、これを確認してください。1もちろん、この問題はJavaでは発生しません。幸いにも

Set(1.0) contains 1 //compiles but is false 

hashCodeはScalaでは==演算子と一致していないため

scala> Set(1.0) contains 1 
res21: Boolean = true 
25

##を導入したことがなければ、我々はこの問題を持っていると思います。 a == bの場合は、aとbのタイプに関係なくa.## == b.##になります(カスタムhashCodeの実装が正しい場合)。他のポスターによって与えられた例に見られるように、同じことはhashCodeについては当てはまりません。

4

##メソッドが等価とハッシュコードとの間で契約を維持しようとしているにもかかわらず、倍精度とlongsを比較しているような場合は、明らかに十分ではないことがある(他のポスターの回答に追加したいスカラー2.10.2):

> import java.lang._ 
import java.lang._ 

> val lng = Integer.MAX_VALUE.toLong + 1 
lng: Long = 2147483648 

> val dbl = Integer.MAX_VALUE.toDouble + 1 
dbl: Double = 2.147483648E9 

> lng == dbl 
res65: Boolean = true 

> lng.## == dbl.## 
res66: Boolean = false 

> (lng.##, lng.hashCode) 
res67: (Int, Int) = (-2147483647,-2147483648) 

> (dbl.##, dbl.hashCode) 
res68: (Int, Int) = (-2147483648,1105199104) 
+0

本当ですか?これはバグですか? –

+0

これは明らかにscaladoC##の通りです。これは値の等価性と一致するハッシュ値を返します.2つの値型インスタンスが真であると比較すると、##はそれぞれに対して同じハッシュ値を生成します。 .. " – starling

+0

スカラー2.11.7でこれをチェックしたところ、' == 'と'。## ==。## ' – EdgeCaseBerg

関連する問題