Sobes.tech
Middle

¿Cómo sobrescribir correctamente el método equals en Java?

sobes.tech AI

Respuesta de la IA

// Ejemplo de sobrescritura mínima correcta de equals
class MyClass {
    private int id;
    private String name;

    public MyClass(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override // Anotación obligatoria
    public boolean equals(Object o) {
        // 1. Comprobación de identidad
        if (this == o) return true;
        // 2. Comprobación de null y coincidencia de clases
        // Usamos getClass() para una comprobación estricta
        if (o == null || getClass() != o.getClass()) return false;
        // 3. Casting
        MyClass myClass = (MyClass) o;
        // 4. Comparación de campos significativos
        return id == myClass.id &&
               // Usamos Objects.equals para comparar objetos (considera null)
               Objects.equals(name, myClass.name);
    }
}

Reglas para una correcta sobrescritura de equals (según el contrato de Object.equals):

  • Reflexividad: Para cualquier valor no nulo x, x.equals(x) debe devolver true.
  • Simetría: Para cualquier x y y no nulos, x.equals(y) debe devolver true si y solo si y.equals(x) devuelve true.
  • Transitividad: Para x, y, y z no nulos, si x.equals(y) y y.equals(z) son true, entonces x.equals(z) debe ser true.
  • Consistencia: Para x y y no nulos, múltiples llamadas a x.equals(y) deben devolver consistentemente true o false, siempre que la información utilizada para la comparación no cambie.
  • Para cualquier x no nulo, x.equals(null) debe devolver false.

Se recomienda usar Objects.equals(obj1, obj2) para comparar objetos de forma segura, ya que maneja correctamente null.

Siempre sobrescriba hashCode() cuando sobrescriba equals(), en conformidad con el contrato general de Object.hashCode: si dos objetos son iguales según equals(Object), sus códigos hash, devueltos por hashCode(), deben ser iguales. La condición inversa no es requerida. No cumplir con esta regla puede causar un funcionamiento incorrecto de colecciones basadas en tablas hash (por ejemplo, HashMap, HashSet).

// Ejemplo de hashCode correspondiente para MyClass
class MyClass {
    private int id;
    private String name;

    // ... constructor y equals como arriba ...

    @Override
    public int hashCode() {
        // Uso de Objects.hash para calcular el hash de forma sencilla
        return Objects.hash(id, name);
    }
}

Se puede generar automáticamente los métodos equals y hashCode usando IDEs (IntelliJ IDEA, Eclipse), lo cual es una buena práctica.

Use instanceof en lugar de getClass() solo si la clase forma parte de una jerarquía de herencia y necesita que objetos de superclases y subclases sean considerados iguales si tienen el mismo estado. En la mayoría de los casos, es preferible usar getClass() para una comprobación estricta.