2012-01-30 14 views
31

Jaka jest różnica między metodami ## i hashCode?Jaka jest różnica między `##` i `hashCode`?

Wydaje się, że wyprowadzają te same wartości bez względu na to, której klasy lub przeciążenia używam w klasie lub hashCode. Google też nie pomaga, ponieważ nie może znaleźć symbolu ##.

+1

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

+3

Mały offtopic, ale możesz szukać takich symboli za pomocą [SymbolHound] (http://www.symbolhound.com/). –

+0

Ah ok. Tak więc, '1.hashCode'' == '' 1. ## 'i' 1.2.hashCode' '==' '. 1.2. ##'. Jedyną rzeczą, która zachowuje się inaczej, jest '1.0.hashCode''! = '' 1.0. ## '(więc '##' jest lepiej przystosowany do porównywania liczb). –

Odpowiedz

32

"podklasy" od AnyVal nie zachowują prawidłowo z perspektywy mieszający:

scala> 1.0.hashCode 
res14: Int = 1072693248 

Oczywiście jest to pudełkowej do wywołania:

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

może Wolimy to być :

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

scala> 1.0.## 
res15: Int = 1 

Powinniśmy xpect to, biorąc pod uwagę, że int 1 jest również double 1. Oczywiście ten problem nie pojawia się w Javie. Bez niego musielibyśmy ten problem:

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

szczęście:

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

## został wprowadzony ponieważ hashCode nie jest zgodny z operatorem w Scala ==. Jeśli a == b to a.## == b.## niezależnie od typu a i b (jeśli niestandardowe implementacje hashCode są poprawne). To samo nie jest prawdą w przypadku hashCode, co widać w przykładach podanych przez inne plakaty.

4

Po prostu chcę dodać do odpowiedzi innych plakatów, że chociaż metoda ## stara się utrzymać kontrakt pomiędzy kodami równości i hashów, to w niektórych przypadkach nie jest wystarczająco dobra, jak w przypadku porównywania podwójnych i długich (scala 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

Naprawdę? Czy to błąd? –

+0

Jest to zgodnie ze skaladoc dla ## "... zwraca wartość skrótu, która jest zgodna z wartością równości: jeśli dwie instancje typu wartości są porównywane jako prawdziwe, to ## będzie dawać tę samą wartość hash dla każdego z nich. .. " – starling

+0

Właśnie sprawdziłem to w scala 2.11.7 i nie widziałem tego samego zachowania dla' == 'i'. ## ==. ## ' – EdgeCaseBerg

Powiązane problemy