Equals

di il
8 risposte

Equals

Buongiorno a tutti sto facendo un esercizio che consiste nel creare una rubrica, che contiene le classi numero, contatto, rubrica allora parto postandovi il codice della classe numero:
package rubrica;

public class Numero {
	private String tipo;
	private String numero;
	
	public Numero(String tipo, String numero){
		this.tipo = tipo;
		this.numero=numero;
	}
	public String getTipo(){
		return tipo;
	}
	public String getNumero(){
		return numero;
	}
	public String toString(){
		return tipo+ ": "+numero;
	}
	public boolean equals(Object o){
		if(this == o)
			return true;
		if(!(o instanceof Numero))
			return false;
		Numero n = (Numero)o;
		return tipo.equals(n.tipo)&&numero.equals(n.numero);
	}
La mia domanda è: il metodo equals usato a cosa serve e come si usa, quel "this ==o"cos'è? "this" a chi si riferisce?
gentilmente qualcuno che mi spieghi in modo molto dettagliato il metodo equals grazie

8 Risposte

  • Re: Equals

    Iron ha scritto:


    La mia domanda è: il metodo equals usato a cosa serve e come si usa, quel "this ==o"cos'è? "this" a chi si riferisce?
    gentilmente qualcuno che mi spieghi in modo molto dettagliato il metodo equals grazie
    Il metodo equals serve per verificare se due oggetti sono di "significato" (contenuto) equivalente. Perché con gli oggetti il == si basa solo sulla identità degli oggetti stessi e non sul loro contenuto.

    equals è definito originariamente in java.lang.Object e in una classe si può ridefinire (override) come hai fatto tu, esattamente con quella forma (a parte il nome del parametro):

    public boolean equals(Object o)

    Il parametro deve restare Object, altrimenti non è un override corretto.

    La prima parte che hai scritto

    if(this == o)
    return true;

    è semplicemente una ottimizzazione. Se l'oggetto passato è, per qualche motivo, lo stesso su cui si invoca il equals, non c'è bisogno di testare altro, è sicuramente "uguale".

    Poi è tipico usare instanceof per verificare il tipo. Se instanceof dà false, è bene restituire false senza altri test. Se invece l'oggetto è del tipo voluto, si fanno i confronti tra gli attributi dei due oggetti, uno è il this, l'altro è l'argomento (convertito al tipo specifico).


    P.S. per il "tipo" del numero presumo intendi es. fisso, mobile, ecc... Per questo si potrebbe usare molto meglio una enum. Se non conosci le enum, ok, usa pure String.

    P.S. 2. Se si ridefinisce equals(), generalmente è bene ridefinire anche hashCode() per mantenere corretto il "contratto" che ci deve essere tra questi due metodi.
  • Re: Equals

    andbin ha scritto:


    Se l'oggetto passato è, per qualche motivo, lo stesso su cui si invoca il equals, non c'è bisogno di testare altro, è sicuramente "uguale".
    Quindi l'oggetto passato sarebbe (o) mentre quello su cui si invoca l'equals sarebbe (this) che corrisponderebbe a:

    Numero numero1 = new Numero(...);??? oppure no?

    andbin ha scritto:


    P.S. per il "tipo" del numero presumo intendi es. fisso, mobile, ecc....
    no l'esercizio per numero intende proprio un numero"33333".

    andbin ha scritto:


    P.S. 2. Se si ridefinisce equals(), generalmente è bene ridefinire anche hashCode() per mantenere corretto il "contratto" che ci deve essere tra questi due metodi.
    Come dovrebbe essere fatto l'hashCode()? grazie
  • Re: Equals

    Iron ha scritto:


    Quindi l'oggetto passato sarebbe (o) mentre quello su cui si invoca l'equals sarebbe (this) che corrisponderebbe a:

    Numero numero1 = new Numero(...);??? oppure no?
    Se fai:
    Numero numero1 = new Numero( .... );
    Numero numero2 = new Numero( .... );
    
    boolean eq = numero1.equals(numero2);  // vediamo se numero1 ha lo stesso contenuto di numero2
    Allora all'interno di equals, quando viene eseguito, il this È numero1 mentre il parametro o (o come lo chiami) È numero2.

    Iron ha scritto:


    no l'esercizio per numero intende proprio un numero"33333".
    Ma io parlavo dell'attributo tipo. Cosa rappresenta?

    Iron ha scritto:


    Come dovrebbe essere fatto l'hashCode()? grazie
    Ti servirebbe tutta la spiegazione sul contratto tra equals() e hashCode().
  • Re: Equals

    andbin ha scritto:


    Se fai:
    Numero numero1 = new Numero( .... );
    Numero numero2 = new Numero( .... );
    
    boolean eq = numero1.equals(numero2);  // vediamo se numero1 ha lo stesso contenuto di numero2
    Allora ho provato a fare quello che hai appena scritto, poi l'ho eseguito su un risolutore di java online per vedere passo passo come si muove il programma e non ho capito un passaggio, quando arriva a:
    if(this == o)
    nonostante io abbia messo i due valori di numero1 e numero 2 identici non mi ritorna true immediatamente ma il puntatore va direttamente all'altro confronti cioè
    if(!(o instanceof Numero))
    poi valuta il resto del programmino e mi ritorna true alla fine, perche non lo fa subito? Perchè quando arriva al primo confronto il puntatore non va proprio su return true?

    andbin ha scritto:


    Ma io parlavo dell'attributo tipo. Cosa rappresenta?
    rappresenta un nome di persona.

    andbin ha scritto:


    Ti servirebbe tutta la spiegazione sul contratto tra equals() e hashCode().
    Il contratto penso di conoscerlo, si basa sulla relazione con equals() cioè se due oggetti sono uguali relativamente al loro metodo equals() allora devono avere anche lo stesso hasCode(). Però il viceversa non è valido.
    La mia domanda era riferita a come dovrei costruirlo nel mio esercizio, dovrei cominciare nel seguente modo:
    public int hasCode(){
    return ...
    cosa dovrebbe ritornare?
  • Re: Equals

    Iron ha scritto:


    if(this == o)
    nonostante io abbia messo i due valori di numero1 e numero 2 identici non mi ritorna true immediatamente
    Come ti ho detto, quella è semplicemente una ottimizzazione, nel "caso" in cui l'oggetto passato sia ESATTAMENTE l'oggetto su cui è invocato il metodo.

    Che avviene es. con:

    numero1.equals(numero1)

    È chiaro che se lo scrivi tu così ... non è molto utile ... è ovvio. Quando è allora che capita? Semplice: può capitare quando ad esempio hai una collezione es. un List e fai

    lista.contains(numero);

    Magari all'interno della lista c'è già un oggetto Numero che è ESATTAMENTE quello stesso oggetto numero che stai passando al contains. Il contains sfrutta equals sugli oggetti e quando arriva a quell'oggetto quel this == o dà true. Che ti ripeto, è una ottimizzazione.

    Iron ha scritto:


    rappresenta un nome di persona.
    E perché allora lo chiami "tipo" ?? E magari allora la classe sarebbe meglio Contatto piuttosto che Numero.

    Iron ha scritto:


    Il contratto penso di conoscerlo, si basa sulla relazione con equals() cioè se due oggetti sono uguali relativamente al loro metodo equals() allora devono avere anche lo stesso hasCode(). Però il viceversa non è valido.
    Sì, corretto.

    Iron ha scritto:


    La mia domanda era riferita a come dovrei costruirlo nel mio esercizio, dovrei cominciare nel seguente modo:
    public int hasCode(){
    return ...
    cosa dovrebbe ritornare?
    Hai 2 attributi String. Ciascuno ha un suo hashCode. Li devi comporre insieme. Generalmente per fare un "buon" hashCode si fa una cosa del tipo:
    int hash = 1;
    hash = 31 * hash + tipo.hashCode();
    hash = 31 * hash + numero.hashCode();
    return hash;
  • Re: Equals

    andbin ha scritto:


    E perché allora lo chiami "tipo" ?? E magari allora la classe sarebbe meglio Contatto piuttosto che Numero.
    perdonami mi sono confuso proprio con la classe Contatto.
    "Tipo" si riferisce ad un numero di ufficio o ad un numero di casa o ad un numero cellulare proprio come avevi intuito precedentemente.

    Un'altra cosa, nello stralcio di programma che ho scritto è necessario inserire i metodi set? cioè scrivere questo;
    public void setTipo(String tipo){
    	this.tipo = tipo;}
    	
    	public void setNumero(String numero){
    	this.numero =  numero;}
    O se non viene scritto non cambia? grazie in anticipo
  • Re: Equals

    Iron ha scritto:


    Un'altra cosa, nello stralcio di programma che ho scritto è necessario inserire i metodi set?
    Se metti i metodi setter rendi i tuoi oggetti "mutabili". Se devono o no essere mutabili ... dipende da come intendi usare gli oggetti.
  • Re: Equals

    andbin ha scritto:


    Se metti i metodi setter rendi i tuoi oggetti "mutabili". Se devono o no essere mutabili ... dipende da come intendi usare gli oggetti.
    Grazie Mille molto gentile
Devi accedere o registrarti per scrivere nel forum
8 risposte