2012-01-30 38 views
31

¿Cuál es la diferencia entre los métodos ## y hashCode?¿Cuál es la diferencia entre `##` y `hashCode`?

Parecen estar emitiendo los mismos valores sin importar qué clase o sobrecarga use hashCode. Google tampoco ayuda, ya que no puede encontrar el símbolo ##.

+1

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

+3

Un poco offtopic, pero puedes buscar esos símbolos usando [SymbolHound] (http://www.symbolhound.com/). –

+0

Ah bien. Entonces, '1.hashCode'' == '' 1. ## ', y' 1.2.hashCode' '==' '1.2. ##'. Lo único que se comporta de manera diferente es '1.0.hashCode''! = '' 1.0. ## '(entonces' ## 'es más adecuado para comparar números). –

Respuesta

32

"subclases" de AnyVal no se comportan adecuadamente desde una perspectiva de hash:

scala> 1.0.hashCode 
res14: Int = 1072693248 

Por supuesto, esto es en caja a una llamada a:

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

Podríamos preferimos que sea :

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

scala> 1.0.## 
res15: Int = 1 

Deberíamos e xpect this dado que el int 1 es también el double 1. Por supuesto, este problema no se presenta en Java. Sin ella, no tendríamos este problema:

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

suerte:

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

## se introdujo porque hashCode no es coherente con el operador == en Scala. Si es a == b, entonces a.## == b.##, independientemente del tipo de ayb (si las implementaciones personalizadas de hashCode son correctas). Lo mismo no es cierto para hashCode como se puede ver en los ejemplos dados por otros carteles.

4

Solo quiero añadir a las respuestas de otros carteles que aunque el método ## se esfuerza por mantener el contrato entre igualdad y códigos hash, aparentemente no es lo suficientemente bueno en algunos casos, como cuando se comparan dobles y largos (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

¿De verdad? ¿Es esto un error? –

+0

Claramente es de acuerdo con scaladoc para ## "... devuelve un valor hash que es consistente con la igualdad de valores: si dos instancias de tipo de valor se comparan como verdaderas, entonces ## producirá el mismo valor hash para cada una de ellas. .. " – starling

+0

Acabo de comprobar esto en la escala 2.11.7 y no vi el mismo comportamiento para' == 'y'. ## ==. ## ' – EdgeCaseBerg

Cuestiones relacionadas