Domanda

Ho sempre pensato che il metodo .equals() in Java dovesse essere sovrascritto per essere reso specifico per la classe che hai creato.In altre parole cercare l'equivalenza di due istanze diverse anziché due riferimenti alla stessa istanza.Tuttavia ho incontrato altri programmatori che sembrano pensare che il comportamento predefinito dell'oggetto dovrebbe essere lasciato invariato e che dovrebbe essere creato un nuovo metodo per testare l'equivalenza di due oggetti della stessa classe.

Quali sono gli argomenti a favore e contro l'override del metodo equals?

È stato utile?

Soluzione

La sovrascrittura del metodo equals è necessaria se si desidera testare l'equivalenza nelle classi della libreria standard (ad esempio, assicurandosi che java.util.Set contenga elementi univoci o utilizzando oggetti come chiavi negli oggetti java.util.Map).

Tieni presente che, se esegui l'override di equals, assicurati di onorare il contratto API come descritto nella documentazione.Ad esempio, assicurati di eseguire anche l'override Oggetto.hashCode:

Se due oggetti sono uguali in base al metodo uguale (oggetto), chiamare il metodo HashCode su ciascuno dei due oggetti deve produrre lo stesso risultato intero.

MODIFICARE:Non l'ho pubblicato come risposta completa sull'argomento, quindi farò eco all'affermazione di Fredrik Kalseth secondo cui l'override di equals funziona meglio per oggetti immutabili.Per citare l'API per Carta geografica:

Nota:È necessario esercitare una grande cura se gli oggetti mutabili vengono utilizzati come tasti della mappa.Il comportamento di una mappa non è specificato se il valore di un oggetto viene modificato in un modo che influenza i confronti uguali mentre l'oggetto è una chiave nella mappa.

Altri suggerimenti

Consiglio vivamente di prendere una copia di Effective Java e di leggere il punto 7 rispettando le istruzioni uguale al contratto.È necessario fare attenzione se si sovrascrive uguale per oggetti mutabili, poiché molte raccolte come Maps e Set utilizzano uguali per determinare l'equivalenza e la modifica di un oggetto contenuto in una raccolta potrebbe portare a risultati imprevisti.Anche Brian Goetz ha un buon talento panoramica dell'implementazione di equals e hashCode.

Non dovresti "mai" sovrascrivere equals e getHashCode per oggetti mutabili: questo vale sia per .net che per Java.Se lo fai, usa un oggetto come la chiave in f.ex un dizionario e poi modifica quell'oggetto, sarai nei guai perché il dizionario si basa sull'hashcode per trovare l'oggetto.

Ecco un buon articolo sull'argomento: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

@David Schlosnagle menziona menziona Josh Bloch Java efficace -- questo è un devi leggere per qualsiasi sviluppatore Java.

C'è un problema correlato:per gli oggetti con valore immutabile, dovresti considerare anche l'override compare_to.La formulazione standard per indicare se differiscono è in API comparabili:

Generalmente è il caso, ma non strettamente richiesto, che (compare(x, y)==0) == (x.equals(y)).In generale, qualsiasi comparatore che viola questa condizione dovrebbe indicare chiaramente questo fatto.La lingua consigliata è "Nota:questo comparatore impone ordinamenti incoerenti con gli uguali."

Il metodo Equals ha lo scopo di confrontare i riferimenti.Quindi non dovrebbe essere sovrascritto per modificarne il comportamento.

Se necessario, dovresti creare un nuovo metodo per verificare l'equivalenza in diverse istanze (o utilizzare il metodo CompareTo in alcune classi .NET)

Ad essere onesti, in Java non esiste un vero argomento contro l'override equivale.Se devi confrontare le istanze per l'uguaglianza, allora è quello che fai.

Come accennato in precedenza, è necessario essere a conoscenza del contratto con codice hash, e allo stesso modo, fai attenzione ai trucchi intorno al Paragonabile interfaccia: in quasi tutte le situazioni in cui desideri ordinamento naturale come definito da Comparable to be coerente con eguali (vedi il BigDecimal api doc per il controesempio canonico)

La creazione di un nuovo metodo per decidere l'uguaglianza, a parte il fatto di non funzionare con le classi della libreria esistente, va in qualche modo contro le convenzioni di Java.

Dovresti solo sovrascrivere il file equals() metodo se si desidera un comportamento specifico quando si aggiungono oggetti a strutture dati ordinate (SortedSet eccetera.)

Quando lo fai dovresti anche eseguire l'override hashCode().

Vedere Qui per una spiegazione completa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top