Domanda veloce: Se desidero utilizzare HashMap
con una classe personalizzata come chiave, deve Ignorare la funzione hashCode
? Come funzionerà se non escludo quella funzione?Utilizzo di HashMap con chiave personalizzata
risposta
Tecnicamente, non è necessario sovrascrivere il metodo hashCode finché gli oggetti uguali hanno lo stesso hashCode.
Quindi, se si utilizza il comportamento predefinito definito da Object, dove equals restituisce solo true solo per la stessa istanza, non è necessario sovrascrivere il metodo hashCode.
Ma se non si esegue l'override dei metodi equals e hashCode, significa che è necessario assicurarsi di utilizzare sempre la stessa istanza chiave.
Es .:
MyKey key1_1 = new MyKey("key1");
myMap.put(key1_1,someValue); // OK
someValue = myMap.get(key1_1); // returns the correct value, since the same key instance has been used;
MyKey key1_2 = new MaKey("key1"); // different key instance
someValue = myMap.get(key1_2); // returns null, because key1_2 has a different hashCode than key1_1 and key1_1.equals(key1_2) == false
In pratica si ha spesso una sola istanza della chiave, quindi tecnicamente non è necessario sovrascrivere i metodi equals e hashCode.
Ma è delle migliori pratiche per ignorare i metodi equals e hashCode per le classi utilizzate come chiavi in ogni caso, perché qualche tempo dopo voi o un altro sviluppatore potrebbe dimenticare che la stessa istanza deve essere utilizzato, che può portare alla difficile tenere traccia dei problemi.
E nota: anche se si sostituiscono i metodi equals e hashCode, è necessario assicurarsi di non modificare l'oggetto chiave in un modo che cambierebbe il risultato dei metodi equals o hashCode, altrimenti la mappa ha vinto ' trovare il tuo valore più Ecco perché è consigliabile utilizzare oggetti immutabili come chiavi, se possibile.
L'unica volta che non c'è bisogno di ignorare la funzione hashCode()
è quando anche voi non ignorare equals
, in modo da utilizzare il valore predefinito Object.equals
definizione di uguaglianza di riferimento. Questo può o non può essere quello che vuoi - in particolare, gli oggetti diversi saranno non essere considerati uguali anche se hanno gli stessi valori di campo.
Se si ignora equals
ma non hashCode
, sarà indefinito HashMap
comportamento (leggi: non farà alcun senso a tutti, e sarà totalmente danneggiati).
Se non si esegue l'override di hashCode AND equivale, si otterrà il comportamento predefinito in base al quale ogni oggetto è diverso, indipendentemente dal suo contenuto.
Dipende dalla classe dell'oggetto utilizzata come chiave. Se è una classe personalizzata come la tua proposta, e non estende nulla (cioè estende Object
) la funzione hashCode sarà quella di Object
, e che prenderà in considerazione i riferimenti di memoria, rendendo due oggetti che hanno lo stesso aspetto per te hash codici diversi.
Quindi sì, a meno che non si stia estendendo una classe con una funzione hashCode()
che sai funzionare per te, è necessario implementare la tua. Assicurati anche di implementare equals()
: alcune classi come ArrayList
utilizzeranno solo eguali mentre altre come HashMap controlleranno sia su hashCode()
e su equals()
.
Hai assolutamente ragione. Ho appena controllato HashMap.put() per essere sicuro, e in effetti avevo sbagliato. Grazie! Ho corretto la risposta per riflettere il tuo commento. – Miquel
Senza verificare i dettagli di implementazione, è possibile vedere che a livello astratto deve essere dovuto all'inevitabilità delle collisioni di hash. Qualsiasi due oggetti in collisione su un hashcode finirebbe lo stesso se non fosse considerato "uguale". –
Considera anche che se la tua chiave non è immutabile potresti avere problemi. Se si inserisce una voce con una chiave mutabile nella mappa e si modifica in seguito la chiave in un modo che influisce su hashcode e equivale a perdere la voce nella mappa, in quanto non sarà più possibile recuperarla.
È necessario eseguire l'override dei metodi equals()
e hashCode()
dalla classe Object. L'implementazione predefinita di equals()
e hashcode()
, che sono ereditati dallo java.lang.Object
, utilizza la posizione di memoria di un'istanza dell'oggetto (ad esempio [email protected]
). Ciò può causare problemi quando due istanze di un oggetto hanno le stesse proprietà ma l'ereditato equals()
restituirà false
perché utilizza lo memory location
, che è diverso per le due istanze.
Anche il metodo toString()
può essere sovrascritto per fornire una rappresentazione stringa corretta del proprio oggetto.
considerazioni principali quando si implementa un utente definito chiave
- Se una classe sostituisce
equals()
, deve sostituirehashCode()
. - Se 2 oggetti sono uguali, anche i loro valori
hashCode
devono essere uguali. - Se un campo non viene utilizzato in
equals()
, non deve essere utilizzato inhashCode()
. - Se si accede spesso,
hashCode()
è un candidato per la memorizzazione nella cache per migliorare le prestazioni.
- 1. Implementazione HashMap personalizzata
- 2. Utilizzo di eval() con una globale personalizzata
- 3. calling containsKey su una hashmap con classe personalizzata
- 4. Utilizzo di ArrayList o HashMap
- 5. Verifica esistenza chiave in HashMap
- 6. Java: chiave composta in hashmap
- 7. Verificare l'esistenza di una HashMap chiave
- 8. ArrayList come chiave in Hashmap
- 9. HashMap con controllo di univocità
- 10. Scala: utilizzo di HashMap con un valore predefinito
- 11. Utilizzo di JSTL come "inserire" un valore in una HashMap
- 12. Java 8 groupingby con chiave personalizzata
- 13. Utilizzo della root personalizzata con FiddlerCore
- 14. Java: ottieni l'indice della chiave in HashMap?
- 15. Bash hashmap utilizzando il preventivo come chiave
- 16. Archiviazione e recupero valore chiave Java HashMap
- 17. È possibile rinominare una chiave Hashmap?
- 18. Confronto delle liste di oggetti con chiave personalizzata
- 19. EL ottenere il valore di un HashMap da Integer chiave
- 20. Java XStream con HashMap
- 21. Utilizzo di HashMap per mappare una stringa e int
- 22. Rails appartiene a has_many con una chiave esterna personalizzata
- 23. ottenere la chiave di una HashMap con una serie di numeri come valore
- 24. Loop di arazzo tramite hashmap
- 25. HashMap (chiave: String, valore: ArrayList) restituisce un oggetto anziché ArrayList?
- 26. Memorizzazione una HashMap all'interno di un altro HashMap miglior rendimento
- 27. Ottieni la chiave da una HashMap utilizzando il valore
- 28. Utilizzo di un array con punti nei valori chiave
- 29. Impostazione degli attributi di utilizzo della chiave con Makecert
- 30. Utilizzo dell'ISession.Get di NHibernate <>() con una chiave composta
A meno che non stia estendendo qualcosa che ha un hashCode che funziona per lui – Miquel