Metodo boolean equals , perche' si usa ?

di il
6 risposte

Metodo boolean equals , perche' si usa ?

Buongiorno .

Vorrei capire e cosa serve e perche' si usa in questo caso il metodo public boolean equals(Object o).
Teoricamente l'ho capito pero' in questo contesto mi e' poco chiaro .
Anche ... Quadrato q = (Quadrato) o .. mi e' poco chiaro .

Posto soltanto una parte di codice di un esercizio ormai famoso in java .

Esercizio per capire il polimorfismo.

Forma e' un'iterfaccia comune alle classi Cerchio, Quadrato , Rettangolo etc...

public interface Forma {

public String getColore ();
public int getDimensione ();
}




public class Quadrato implements Forma {

private String colore;
private int dimensione;

public Quadrato(int d, String c) {
this.colore = c;
this.dimensione = d;
}

public String getColore() {
return this.colore;
}

public int getDimensione() {
return this.dimensione;
}

public boolean equals(Object o) {
if (o.getClass() != this.getClass())
return false;
Quadrato q = (Quadrato) o;
return (this.colore.equals(q.getColore()) && (this.dimensione == q.getDimensione()));
}
public int hashCode() {
return (this.colore.hashCode()+ dimensione);
}

}

6 Risposte

  • Re: Metodo boolean equals , perche' si usa ?

    I metodi booleani sono metodi che ritornano un risultato vero o falso...
    Per esempio:
    Se volessi sapere se ci sono monete da 50 cent in un cambia monete, invoco il modeto
    public boolean ciSonoMoneteDa50Cent(){
    Il corpo del metodo effettua il
    controllo e se trova monete da 50
    Cent ritorna true altrimenti false
    return boolean
    }

    puoi creare altri metodi:
    public boolean ciSonoMoneteDa1Euro(){
    Il corpo del metodo effettua il
    controllo e se trova monete da 1
    Euro ritorna true altrimenti false
    return boolean;
    }

    I metodi booleani sono una convenzione non fanno parte della semantica di java

    come i metodi get e set, per essere chiari
  • Re: Metodo boolean equals , perche' si usa ?

    FabioJ ha scritto:


    Vorrei capire e cosa serve e perche' si usa in questo caso il metodo public boolean equals(Object o).
    equals è stato definito in java.lang.Object e può essere ri-definito (override) in una sottoclasse per stabilire se due oggetti sono di significato/contenuto "equivalente". Questo perché il solo operatore == (o !=) si basa solo sulla "identità" degli oggetti e non sul loro contenuto.

    FabioJ ha scritto:


    Anche ... Quadrato q = (Quadrato) o .. mi e' poco chiaro .
    Questo è un semplice "down" cast. Il parametro è Object ma tu vuoi vedere l'oggetto come un Quadrato. Chiaramente l'oggetto deve realmente essere un Quadrato! Presupporrebbe di fare PRIMA un test con l'operatore instanceof

    FabioJ ha scritto:


    public boolean equals(Object o) {
    if (o.getClass() != this.getClass())
    return false;
    Quadrato q = (Quadrato) o;
    return (this.colore.equals(q.getColore()) && (this.dimensione == q.getDimensione()));
    }
    Non è correttissimo al 100%. L'argomento può essere null (equals deve dare false in tal caso). Ma o.getClass() ovviamente causa un NullPointerException su un null.

    Il test del tipo con il Class non è sbagliato. E' solamente più "stretto" e pignolo perché non considera la ereditarietà.
  • Re: Metodo boolean equals , perche' si usa ?

    Vi ringrazio e bravi come al solito.
    Pero' devo dire che non ho ancora capito in questo esercizio perche' viene utilizzato il public boolean.
    Ripeto la teoria la conosco abbastanza e so che avrò un ritorno false o true pero' vorrei procedere in bicicletta e non con un GoKart.
    Scusate questo esempio cretino della bicicletta e il Kart pero' logicamente le seguenti istruzioni cosa fanno:
    Se o.getClass() e' diverso da ????? perche' si scrive l'istanza .....this.getClass() ritorna false altrimenti .....return etc...
    In poche parole , cosa succede

    public boolean equals(Object o) {
    if (o.getClass() != this.getClass())
    return false;
    Quadrato q = (Quadrato) o;
    return (this.colore.equals(q.getColore()) && (this.dimensione == q.getDimensione()));
    }
    public int hashCode() {
    return (this.colore.hashCode()+ dimensione);
  • Re: Metodo boolean equals , perche' si usa ?

    FabioJ ha scritto:


    Pero' devo dire che non ho ancora capito in questo esercizio perche' viene utilizzato il public boolean.
    Il metodo in java.lang.Object è:

    public boolean equals(Object obj)

    E per le regole del overriding, in una sottoclasse DEVE restare esattamente così (a parte il nome del parametro, che è arbitrario).
    Non puoi restringere il livello di accesso, non puoi cambiare il tipo di ritorno, non puoi dichiarare eccezioni checked e non puoi nemmeno cambiare il tipo del parametro (altrimenti fai un overload ... non un ovverride).

    In una sottoclasse deve restare dichiarato così.

    FabioJ ha scritto:


    Ripeto la teoria la conosco abbastanza e so che avrò un ritorno false o true pero' vorrei procedere in bicicletta e non con un GoKart.
    Scusate questo esempio cretino della bicicletta e il Kart pero' logicamente le seguenti istruzioni cosa fanno:
    Se o.getClass() e' diverso da ????? perche' si scrive l'istanza .....this.getClass() ritorna false altrimenti .....return etc...
    In poche parole , cosa succede
    Ok, facciamo un esempio più semplice:
    class Persona {
        private final String nome;
    
        public Persona(String nome) {
            this.nome = nome;
        }
    
        public String getNome() {
            return nome;
        }
    }
    Il equals posso implementarlo in almeno due modi: usando instanceof per il test o usando il test sulle classi:

    a)
        public boolean equals(Object obj) {
            if (obj instanceof Persona) {
                Persona altraPersona = (Persona) obj;
                return nome.equals(altraPersona.nome);
            }
    
            return false;
        }
    b)
        public boolean equals(Object obj) {
            if (obj != null && obj.getClass() == getClass()) {
                Persona altraPersona = (Persona) obj;
                return nome.equals(altraPersona.nome);
            }
    
            return false;
        }
    La differenza è nel test che VA sempre fatto prima nel equals.
    L'operatore instanceof rispetta la ereditarietà, verifica se l'oggetto soddisfa la condizione IS-A ("è-un") Persona. Se io facessi una sottoclasse

    class Studente extends Persona { ..... }

    e faccio
    Persona unaPersona = new Persona("Mario");
    Studente unoStudente = new Studente("Mario");
    
    if (unaPersona.equals(unoStudente))
    la condizione con instanceof è soddisfatta (e equals darà true poiché i nomi sono uguali), infatti un oggetto Studente è-un Persona.

    Mentre invece con il test delle classi con getClass() il test è molto più stretto. Per ogni classe definita in Java c'è un corrispondente oggetto di tipo java.lang.Class associato.
    Il class di Persona è un certo oggetto Class, il class di Studente è un ALTRO oggetto Class. Quindi confrontando i Class, il test è molto rigido e NON rispetta la ereditarietà. Un oggetto di classe Studente NON ha il Class di Persona quindi il test fallisce (e farà il return false).
  • Re: Metodo boolean equals , perche' si usa ?

    If(o.getClass()!= this.getClass())
    getClass() ritorna l'oggetto.
    Quindi l'istruzione confronta se i due oggetti sono uguali
    e ritorna il risultato false se sono oggetti diversi

    altrimenti
    gli oggetti sono sicuramente uguali

    faccio un cast dell'oggeto o a q
    oppure diciamo che definisco l'oggetto o come oggetto di tipo Quadrato

    Quadrato q = (Quadrato) o;

    ritorno true o false il che dipende dalla condizione qui sotto...
    Qui lui verifica se il colore di quest'oggetto è uguale all'oggeteo q
    return (this.colore.equals(q.getColore())
    e se la dimensione di quest'oggetto è uguale a quella di q
    && (this.dimensione == q.getDimensione()));
    quindi ritorno true o false a seconda dell'operazione.

    l hascCode è un metodo Override
    Non so bene cosa sia l'hascCode però mi sembra di capire che è una sorta di ID
  • Re: Metodo boolean equals , perche' si usa ?

    @FabioJ, stai facendo pasticci:

    1) l'operatore == confronta oggetti PRIMITIVI: quindi interi, float, caratteri, boolean. Nel caso degli Oggetti (che derivano da Object, un int NON DERIVA DA Object, un Integer DERIVA DA Object!!!), confronta I PUNTATORI (perche', alla fin fine, anche se non li vedi, anche in Java gli oggetti sono gestiti da puntatori)
    2) visto che l'operatore == fa il confronto tra puntatori, COME FAI A CONFRONTARE due oggetti attraverso il CONTENUTO?
    Mediante il metodo 'equals' che PER DEFAULT (visto che e' implementato nella classe Object) fa il confronto tra PUNTATORI.

    Perche' serve? Perche' una classe contiene, in generale, field che servono per gestire LO STATO delle istanze, e field di servizio CHE NON DEVONO ESSERE CONSIDERATI come parte dello stato dell'oggetto.

    Ad esempio, supponi di assegnare ad ogni oggetto che crei un id univoco, che ti serve SOLO PER DEBUG. Quando confronti due oggetti, divi controllare i field che ne descrivono lo stato MA NON il field che contiene l'id.

    Da un oggetto, puoi sempre chiedere a quale classe appartiene (getClass()).
    TUTTI gli oggetti di quella classe fanno riferimento ALLO STESSO OGGETTO Class CHE DESCRIVE LA classe.

    Si, lo so, e' un pasticcio di termini, ma concettualmente e' semplice :

    1) ogni oggetto appartiene ad una classe
    2) l'oggetto che DESCRIVE una classe e' un ISTANZA della classe "Class" e la classe "Class" DERIVA da "Object"
    3) l'ISTANZA della classe "Class" che descrive la classe "Class" e' un oggetto che ha come classe "Class" (questa e' cattiva )
    4) tutte le ISTANZE della classe "C" puntano all' UNICO oggetto della classe "Class" che descrive la classe "C"

    QUINDI, se tu hai gli oggetto a1, a2 della classe A e l'oggetto b1 della classe B, se vuoi sapere se a1 e a2 appartengono alla stessa classe, basta scrivere

    a1.getClass() == a2.getClass() --> true

    mentre

    a1.getClass() == b1.getClass() --> false

    Questo, ripeto, perche' x.getClass() ritorna il PUNTATORE all'oggetto di classe "Class" che descrive la classe, e questo e' UNICO per ogni classe e classi distinte sono associate a oggetti "Class" distinti.


    Il giochino dell'hashCode e' TUTTA un'altra storia.

    NON BASTA definire il metodo 'hashCode()' MA SERVE anche 'equals()':

    due oggetti sono DIVERSI se 'hashCode()' ritorna valori DIVERSI

    MA NON E' DETTO SIANO UGUALI se il valore hash e' uguale!!!!! Te ne devi accertare con il metodo 'equals()' !!!!!

    E' un casino?
    Certamente che lo e' !
    Se fosse facile, come faremmo a chiedere stipendi stratosferici

Devi accedere o registrarti per scrivere nel forum
6 risposte