Quando utilizzare il confronto delle identità anziché gli uguali?

1

Mi chiedo perché qualcuno vorrebbe usare il confronto delle identità per i campi in equals , come qui (sintassi Java):

class C {
    private A a;

    public boolean equals(Object other) {
        // standard boring prelude
        if (other==this) return true;
        if (other==null) return false;
        if (other.getClass() != this.getClass()) return false;
        C c = (C) other;

        // the relevant part
        if (c.a != this.a) return false;

        // more tests... and then
        return true;
    }

    // getter, setters, hashCode, ...
}

L'utilizzo di == è un po 'più veloce di equals e un po' più breve (a causa della mancanza di test nulli), ma in quali casi (se ce ne sono) diresti che è molto meglio usa == per i campi all'interno di equals ?

    
posta maaartinus 05.10.2012 - 23:00
fonte

4 risposte

2

Ci sono casi in cui è necessario verificare l'uguaglianza di istanza con == . Ad esempio, questo è ciò che fai nell'implementazione di equals per verificare se stai confrontando un oggetto con se stesso (una scorciatoia molto importante che soddisfa anche il requisito di reflessività di equals )

if (other==this) return true;

L'altro caso è quando il sistema garantisce che ci sarà una sola istanza uguale a qualsiasi oggetto di una particolare classe (e necessariamente che sarà l'istanza stessa), ancora una volta, a causa della riflessività di equals ). Questo è un altro caso comune illustrato dal frammento di codice:

if (other.getClass() != this.getClass())

Un'uguaglianza di due oggetti java.lang.Class equivale all'uguaglianza dei loro riferimenti, perché per ogni classe definita esiste una sola istanza di java.lang.Class .

Un terzo caso in cui si desidera l'uguaglianza di riferimento è la serializzazione: è necessario tenere traccia delle istanze dell'oggetto rintracciando i loro riferimenti, anche se sono logicamente uguali, in modo da essere in grado di produrre un grafico isomorfo sulla deserializzazione.

EDIT: all'interno di implementazioni di equals l'uso di == si riduce all'aumento delle prestazioni: il confronto di un oggetto su se stesso è un caso comune, specialmente quando si usano oggetti della classe come chiavi in una tabella hash, quindi ha senso ottimizzarlo.

    
risposta data 05.10.2012 - 23:10
fonte
1

Il == operator in Java controlla l'uguaglianza di riferimento: restituisce true se i puntatori sono uguali. Non controlla l'uguaglianza dei contenuti.

Utilizza il metodo equals () per confrontare i valori dell'oggetto. Il metodo equals () restituisce un valore booleano.

I due operatori che possono essere utilizzati con i riferimenti agli oggetti stanno confrontando per equality (==) e inequality (!=). Questi operatori confrontano due valori per vedere se si riferiscono allo stesso oggetto. Anche se questo confronto è molto veloce, spesso non è quello che vuoi. Di solito vuoi sapere se gli oggetti hanno lo stesso valore e non se due oggetti sono un riferimento allo stesso oggetto. Ad esempio,

if (name == "My Test Value")   // Legal, but ALMOST SURELY WRONG

Questo è vero solo se il nome è un riferimento allo stesso oggetto a cui si riferisce "Il mio valore di prova". Questo sarà falso se la stringa nel nome è stata letta dall'input o calcolata (mettendo insieme le stringhe o prendendo la sottostringa), anche se il nome contiene esattamente quei caratteri.

Molte classi (ad esempio, String) definiscono il metodo equals() per confronta i valori degli oggetti.

    
risposta data 05.10.2012 - 23:04
fonte
0

È vero che molto spesso usiamo == invece di equals() solo per le prestazioni, dove chiamare equals() farebbe altrettanto bene, ma esistono casi in cui è necessario utilizzare == .

Ad esempio, se disponi di un elenco che consente valori duplicati (più istanze diverse che appaiono uguali in base ai loro metodi equals() ) e desideri rimuovere una determinata istanza dall'elenco, non puoi utilizzare equals() per trovare l'istanza da rimuovere, perché equals() ti troverà il primo duplicato, non l'istanza esatta che stai cercando. Per trovare l'istanza esatta, devi utilizzare == .

Naturalmente, questo è solo un esempio semplicistico. Per saperne di più sul perché sia == che equals() sono assolutamente necessari, è necessario leggere il concetto di semantica di valori rispetto a semantica di riferimento . (Ho cercato una buona fonte di informazioni sull'argomento ma non ho trovato nulla di ben scritto, se qualcuno trova qualcosa di buono, per favore pubblica!)

    
risposta data 05.10.2014 - 12:29
fonte
0

È davvero raro quando si vuole fare uguaglianza di riferimento ( == ) invece di uguaglianza logica ( equals() ). Spesso quando ti ritrovi a controllare l'uguaglianza di riferimento, potrebbe esserci qualcosa di sbagliato nel tuo progetto o potresti voler implementare il metodo equals() .

Tuttavia, c'è un caso in cui controllo spesso l'uguaglianza di riferimento (non sono sicuro che sia una buona pratica):

public void actionPerformed(ActionEvent e){
    AbstractButton source = (AbstractButton) e.getSource();

    if (source == someButton)
        doStuff();
    else if (source == someOtherButton)
        doSomethingElse();
    // ...
}
    
risposta data 05.10.2014 - 13:25
fonte

Leggi altre domande sui tag