Como implementar el método equals

De ChuWiki
Saltar a: navegación, buscar

Implementación del método equals en un objeto

  • Se deben sobreescribir los siguiente métodos
    • public boolean equals(Object )
    • public int hashCode()
      • calcula una función hash("resumen") sobre el objeto muchas clases (Hashtable por ejemplo) lo invocan.
  • Este es el orden en el que serán invocados los métodos para comparar dos objetos:
  1. Se invoca hashCode() de ambos métodos
  2. Si es distinto, los objetos son distintos
  3. Si es igual, no es concluyente y se invoca el método equals()
  • Esto explica porque una Hashtable es más eficiente que una lista en el acceso a sus elementos
  • Propiedades que debe cumplir el método equals()
    • Reflexivo
    • Simétrico
    • Transitivo
    • No nulo (un this nunca será igual a null)
    • Consistente (multiples llamadas darán el mismo resultado)
  • No se incluyen en el cálculo de equals campos static (clase) o transient (serialización)
  • Implementación de equals en un objeto con un atributo:
   public boolean equals(Object objeto) 
   { 
       //Reflexivo 
       if ( this == objeto ) return true; 
        
       //No nulo 
       if ( objeto == null ) return false; 
      
       //Simetrico 
       //La máquina virtual mantiene una única instancia de cada clase, por lo que esta comparación es correcta 
       //Usar instanceof no garantiza la simetría porque es true para una clase y sus hijos 
       if ( this.getClass() != objeto.getClass() ) return false; 

       // una vez que sabemos que son del mismo tipo hacemos cast para que el compilador lo sepa también
       if ( this.atributo == this.getClass().cast(objeto).atributo ) return true; 

       if ( this.atributo != null ) return this.atributo.equals( this.this.getClass().cast(objeto).atributo ); 
  }
  • Es recomendable hacer las comparaciones con los atributos primitivos primero
    • Se realizan más rápido, con lo que si alguno es false, no hay que seguir comparando
  • Implementación de hashCode. Es deseable
    • Calculos poco costosos
    • multiplicaciones,
    • operaciones a nivel de bit
    • evitar sumas (usar XOR en su lugar)
    • calculo en el momento de creación para objetos de solo lectura
    • Resultados dispersos (lo más distintos posible)
    • multiplicaciones por números primos
  • Notas
    • Un String (ni cualquier otro objeto) no debe compararse con == (sólo funciona sin ambos han sido creados de la forma String cadena="texto"; )
    • Clases que heredan de Number
      • Double.POSITIVE_NUMBER
        • == Double.POSITIVE_INFINITY+1 -->TRUE
        • equals(Double.POSITIVE_INFINITY+1 ) TRUE
      • Double.NEGATIVE_NUMBER
        • == Double.NEGATIVE_INFINITY+1 -->TRUE
        • equals(Double.NEGATIVE_INFINITY+1 ) TRUE
      • Double.NaN
        • == Double.NaN -->FALSE
        • equals(Double.NaN ) -->TRUE
    • Autoboxing en Java 5 ("casting implícito" de tipos, por ejemplo double/Double cuando lo necesita)
      • Double a = new Double(7);
      • Double c = new Double(7);
      • double b = 7;
      • ( a == b ) -->TRUE
      • a.equals(b) -->TRUE
      • ( b == c ) -->TRUE
      • c.equals(b) -->TRUE
      • ( a == c ) -->FALSE
      • c.equals(a) -->TRUE