2011-12-01 17 views
12

Ho trovato spesso un metodo di uguaglianza in posti diversi. Cosa fa in realtà? È importante che dobbiamo avere questo in ogni classe?Cosa fa equals (Object obj)?

public boolean equals(Object obj) 
    { 
    if (obj == this) 
    { 
     return true; 
    } 
    if (obj == null) 
    { 
     return false; 
    } 
    if (obj instanceof Contact) 
    { 
     Contact other = (Contact)obj; 
     return other.getFirstName().equals(getFirstName()) && 
       other.getLastName().equals(getLastName()) && 
       other.getHomePhone().equals(getHomePhone()) && 
       other.getCellPhone().equals(getCellPhone()); 

    } 
    else 
    { 
     return false; 
    } 
} 
+4

Presumo che abbiate già consultato la documentazione, che lo spiega chiaramente: http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html [scorrere verso il basso per equals() come il collegamento diretto non sembra funzionare in commments]. – NPE

risposta

31

ridefinisce "l'uguaglianza" degli oggetti.

Per impostazione predefinita (definita in java.lang.Object), un oggetto è uguale a un altro oggetto solo se si tratta della stessa istanza. Ma puoi fornire una logica di uguaglianza personalizzata quando la sostituisci.

Ad esempio, java.lang.String definisce l'uguaglianza confrontando l'array di caratteri interno. Ecco perché:

String a = new String("a"); //but don't use that in programs, use simply: = "a" 
String b = new String("a"); 
System.out.println(a == b); // false 
System.out.println(a.equals(b)); // true 

Anche se potrebbe non essere necessario testare l'uguaglianza in questo modo, le classi che si utilizzano fanno. Ad esempio, le implementazioni di List.contains(..) e List.indexOf(..) utilizzano .equals(..).

Controllare the javadoc per il contratto esatto richiesto dal metodo equals(..).

In molti casi, quando si esegue l'override di equals(..), è necessario eseguire l'override di hashCode() (utilizzando gli stessi campi). Questo è anche specificato in javadoc.

1

Esso consente di ri-definire quali oggetti sono uguali e non, per esempio, si può definire che due Person oggetti come uguali se il Person.ID è uguale o se il Weight è uguale a seconda della logica nell'applicazione.

Vedi questo: Overriding the java equals() method quirk

11

classi diverse hanno diversi criteri per ciò che rende 2 oggetti "uguali". Normalmente, equals() restituisce true se è lo stesso oggetto:

Object a = new Object(); 
Object b = new Object(); 
return(a.equals(b)); 

Ciò restituirà falso, nonostante sapessero che sono entrambe le classi "oggetto", non sono la stessa istanza. a.equals(a) restituirà true.

Tuttavia, in casi come una stringa, è possibile avere 2 casi diversi, ma String uguaglianza è basata su caratteri letterali che compongono quelle stringhe:

String a = new String("example"); 
String b = new String("example"); 
String c = new String("another"); 
a.equals(b); 
a.equals(c); 

Queste sono tutte diverse istanze di String, ma la i primi equals restituiranno true perché sono entrambi "example", ma il 2 non lo farà perché "example" non è "another".

Non è necessario eseguire l'override di equals() per ogni classe, solo quando esiste un caso speciale per l'uguaglianza, come una classe che contiene 3 stringhe, ma solo la prima stringa viene utilizzata per determinare l'uguaglianza. Nell'esempio che hai pubblicato, potrebbe esserci stato un altro campo, description, che potrebbe essere diverso per 2 diversi "Contatti", ma 2 "Contatti" saranno considerati uguali se quei 4 criteri corrispondono (nome/cognome e casa/cellulare numeri), mentre la descrizione corrispondente o non corrispondente non gioca se 2 Contatti sono uguali.

3

Il metodo equals viene utilizzato quando si desidera sapere se due oggetti sono equivalenti in base alla definizione che gli oggetti trovano adatti.Ad esempio, per gli oggetti String, l'equivalenza riguarda se i due oggetti rappresentano la stessa stringa di caratteri. Pertanto, le classi spesso forniscono la propria implementazione di equals che funziona nel modo naturale per quella classe.

Il metodo equals è diverso da == in quanto quest'ultimo verifica l'identità dell'oggetto, ovvero se gli oggetti sono gli stessi (che non è necessariamente uguale all'equivalente).

8

A parte tutto ciò che data dal Bozho, ci sono alcune cose aggiuntive di essere a conoscenza di se prioritario è uguale:

  • qualcosa.equals(null) deve sempre return false - vale a dire nulla non è uguale a qualsiasi altra cosa. Questo requisito è curato nel secondo se del tuo codice.

  • se è vero che qualcosa == qualcos'altro, poi anche qualcosa.equals(qualcos'altro) deve anche essere vero. (Ad esempio, gli oggetti identici devono essere uguali) Il primo se del codice si occupa di questo.

  • .equals DOVREBBE essere simmetrico per oggetti non nulli, ad esempio a.equals(b) dovrebbe essere lo stesso di b.equals(a). A volte, questo requisito si interrompe se la sottoclasse e la sovrascrittura sono uguali nella classe genitore e nella sottoclasse. Spesso equals contiene codice come if (!getClass().equals(other.getClass())) return false; che almeno si assicura che un tipo di oggetto diverso non sia uguale l'uno con l'altro.

  • Se si ignora equals anche voi dovete ignorare hashCode tale che la seguente espressione vale: if (a.equals(b)) assert a.hashCode() == b.hashCode(). Cioè il codice hash di due oggetti uguali tra loro deve essere uguale. Si noti che il contrario non è vero: due oggetti che hanno lo stesso codice hash possono o non possono essere uguali tra loro. Di solito, questo requisito viene preso in considerazione derivando l'hashCode dalle stesse proprietà utilizzate per determinare l'uguaglianza di un oggetto.

Nel tuo caso, il metodo hashCode potrebbe essere:

public int hashCode() { 
    return getFirstName().hashCode() + 
    getLastName().hashCode() + 
    getPhoneHome().hashCode() + 
    getCellPhone().hashCode(); 
} 
  • Se si implementa Comparable che mette a confronto due oggetti se sono più piccoli, più grande, o uguali tra loro, a.compareTo(b) == 0 dovrebbe essere vero se e solo se a.equalTo(b) == true

In molti IDE (es. Eclipse, IntelliJ IDEA, NetBeans) ci sono caratteristiche che g enerate entrambi per equals e per voi, risparmiandovi così il lavoro noioso e probabilmente soggetto a errori.

Problemi correlati