2012-01-30 65 views
31

Qual è la differenza tra i metodi ## e hashCode?Qual è la differenza tra `##` e `hashCode`?

Sembra che stiano emettendo gli stessi valori indipendentemente da quale classe o sovraccarico hashCode utilizzo. Anche Google non aiuta, in quanto non riesce a trovare il simbolo ##.

+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 po 'fuori programma, ma è possibile cercare tali simboli usando [SymbolHound] (http://www.symbolhound.com/). –

+0

Ah ok. Quindi, '1.hashCode'' ==' '1. ##', e '1.2.hashCode'' == '' 1.2. ## '. L'unica cosa che si comporta diversamente è '1.0.hashCode''! = '' 1.0. ## '(quindi' ## 'è più adatto per confrontare i numeri). –

risposta

32

"sottoclassi" di AnyVal non si comportano correttamente dal punto di vista di hashing:

scala> 1.0.hashCode 
res14: Int = 1072693248 

naturalmente questo è inscatolato ad una chiamata a:

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

Potremmo preferiamo che sia :

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

scala> 1.0.## 
res15: Int = 1 

Dobbiamo xpetto questo dato che lo int 1 è anche il double 1. Ovviamente questo problema non si verifica in Java. Senza di essa, avremmo questo problema:

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

fortuna:

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

## è stato introdotto perché hashCode non è coerente con la == operatore in Scala. Se a == b quindi a.## == b.## indipendentemente dal tipo di aeb (se le implementazioni personalizzate hashCode sono corrette). Lo stesso non è vero per hashCode come si può vedere negli esempi forniti da altri poster.

4

Voglio solo aggiungere alle risposte degli altri poster che sebbene il metodo ## si impegni a mantenere il contratto tra i codici di uguaglianza e hash, in alcuni casi non è abbastanza buono, come quando si confrontano i doppi e i lunghi (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

Davvero? è un insetto? –

+0

È chiaramente come secondo scaladoc per ## "... restituisce un valore di hash che è coerente con l'uguaglianza di valore: se due istanze di tipo valore vengono confrontate come vere, allora ## produrrà lo stesso valore di hash per ognuna di esse. .. " – starling

+0

Ho appena controllato questo in scala 2.11.7 e non ho visto lo stesso comportamento per' == 'e'. ## ==. ## ' – EdgeCaseBerg

Problemi correlati