2014-11-08 13 views
5

L'ultimo paragrafo del punto 9 di Effective Java, secondo Edn, J. Bloch dice che, per le classi di valore come Integer, String, Date ecc, ritorno in funzione del valore esatto di tale classe come il non è una buona idea.Perché il valore di una classe di valori come hashCode "non è una buona idea"?

Quindi, la classe Integer restituisce il value del numero intero che rappresenta come hashCode della sua istanza non è tutto così buono.

Né è la hashCode() di String restituendo un valore intero mappato direttamente dal contenuto globale, cioè, i caratteri che l'istanza String contiene.

Questi hashCode() -s sono chiaramente conformi al contratto.

Per me, sembra essere una buona idea, piuttosto che una cattiva tra-- le hashCode -s variano i valori variano tra gli oggetti, e questi hashCodes sono "normalizzati" prima di essere distribuiti nei secchi di un HashMap/HashSet - in modo che le hashCode -s delle voci non costituiscono un pregiudizio su cui secchio voce andrà in

Cosa mi manca qui -. ciò che rende la mappatura del valore di classe direttamente a hashCode un "cattivo idea"?

TIA

// ===========================

EDIT

pls anche vedere commenti sotto la risposta di Steve Siebert in relazione a questo.

risposta

4

quello che sta dicendo è che coloro specifiche javadoc dire esattamente come viene creata la hashCode. In questo modo, le applicazioni ora possono dipendere da questo sempre per essere vero ... e ora quelle implementazioni non possono mai cambiare il modo in cui viene generato l'hashCode.

Ciò non significa che non si debba derivare il proprio hash dai propri valori ...solo che non dire alla gente come si fa questo nella vostra specifica =)

+0

d'accordo. ma la soluzione a questo dovrebbe forzare un principio che "il' hashCode' shdn't essere usato come un indicatore/sostituto funzionale di 'value'", piuttosto di entrare tra quella bella relazione tra 'valore' e' hashCode() 'e quindi tra' equals() 'e' hashCode() '. – Roam

+0

Sono assolutamente d'accordo con te, un hashCode può in pratica essere trattato come uno che restituisce una rappresentazione "meno intelligente/lossy" del valore reale dell'oggetto - suscettibile al paradosso del compleanno. Ma, in realtà, un hash non è necessario * bisogno * di avere una relazione con valore ... hashCode ha bisogno di restituire sempre lo stesso valore int per lo stesso oggetto (tuttavia questo è definito da te) in modo che l'oggetto possa essere trovato in il secchio atteso. Normalmente questo viene fatto tagliando uno/più valori dell'oggetto ... ha senso. Ma, se si potesse fare, dica ... magia ... allora chi sono io per giudicare? =) –

+0

aggrappando 'hashCode' a' value' è probabile che assicuri "se due oggetti non sono uguali, di quanto non lo siano i loro hashCode" e questa è una buona cosa avere per voci distribuite uniformemente tra i bucket hash-- sebbene non sia un requisito dal contratto. non ho visto né posso pensare a un modo migliore di farlo. – Roam

-1

L'API Java fa proprio questo, restituisce l'intero.

Integer t = ...; 
t.intValue() == t.hashCode(); // true 

Ho lo stesso libro al lavoro. Lo guarderò lunedì.

Se sei veramente preoccupato, implementare il FNV-1a hash:

int hash = 0x4C1DF00D; 
    hash = (hash^value) * 0x01000193; 
+0

Mi chiedo perché il downvote? Stavo pensando di arrivare alla stessa conclusione di @SotiriosDelimanolis, ma ho il libro altrove e non sapevo che fosse disponibile gratuitamente online. –

3

Il full quote è

Molte classi nelle librerie della piattaforma Java, come ad esempio String, Integer e Date, includere nel loro specifiche il valore esatto restituito dal loro metodo hashCode come una funzione del valore di istanza. Questa non è generalmente una buona idea, in quanto limita fortemente le tue capacità per migliorare la funzione di hash nelle versioni future. Se si lasciano le dettagli di una funzione di hash non specificato e un difetto si trova o una migliore funzione hash scoperto, è possibile modificare la funzione di hash in un successivo rilascio, sicuro che nessun client dipendono dai esatte valori restituiti dalla hash funzione.

Enfasi mia. Il libro sta solo affermando che è generalmente considerata una cattiva pratica rivelare dettagli di implementazione in una specifica. Questo lo rende resistente ai cambiamenti.

Il fatto che sia stato implementato restituendo un valore esatto (per Integer) o un valore calcolato (per Date e String) non è male.

Problemi correlati