En caso de que los objetos que tienen el mismo hash ser igual?

TMOTTM:

En este ejemplo, a continuación, se crea dos objetos que tienen exactamente la misma estructura interna. Ambos llevan nada más que el valor 1 como una variable de instancia. Mi pensamiento es que si tomo el hash del e1que debe ser el mismo que el hash de e2y por lo tanto e1.equals(e2)debe devolver verdadero.

class EqualsChecker {

    public static void main(String[] args) {

        Elem e1 = new Elem(1);
        Elem e2 = new Elem(1);


        System.out.println(e1);                                // EqualsChecker$Elem@6ff3c5b5
        System.out.println(e2);                                // EqualsChecker$Elem@3764951d
        System.out.println("e1.equals(e2): " + e1.equals(e2)); // returns false
    }


    static class Elem {
        private int v;
        public Elem(int i) {
            this.v = i;
        }   
    }   
}

¿Por qué equalsfalsa regreso aquí? Creo que tengo el caso media en el siguiente dibujo:introducir descripción de la imagen aquí

Arvind Kumar Avinash:

Mira los siguientes puntos de https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#hashCode--

  1. Cada vez que se invoca en el mismo objeto más de una vez durante una ejecución de una aplicación Java, el método hashCode debe volver consistentemente el mismo número entero, siempre que no la información utilizada en las comparaciones Igual en se modifica el objeto. Este número entero no necesita permanecer consistentes de una ejecución de una aplicación a otra ejecución de la misma aplicación.
  2. Si dos objetos son iguales de acuerdo con el método equals (Object), a continuación, una llamada al método hashCode en cada uno de los dos objetos debe producir el mismo resultado entero.
  3. No es necesario que si dos objetos son desiguales según el método equals (java.lang.Object), después de llamar al método hashCode en cada uno de los dos objetos debe producir resultados enteros distintos. Sin embargo, el programador debe ser consciente de que la producción de resultados enteros distintos de objetos desiguales puede mejorar el rendimiento de las tablas hash.
  4. Tanto como sea razonablemente práctico, el método hashCode definido por la clase Object no devolver enteros diferentes para objetos distintos. (El hashCode puede o no puede ser implementado como una función de dirección de memoria de un objeto en algún punto en el tiempo).

Ahora, mira el siguiente código y su salida:

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

Salida:

true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
false
employee2.hashCode(): 1297685781

Dado que employee3se apuntan al mismo objeto como employee1, que está recibiendo el mismo código hash para ellos mientras employee2está apuntando a un objeto diferente (aunque tiene el mismo contenido, la palabra clave, newcreará un objeto separado en la memoria) y, por tanto, es posible que raramente obtener el mismo código hash para employee2que el punto # 4 mencionado anteriormente a partir de los estados de documentación:As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.

Debe invalidar hashCodeel método de manera que debe devolver el mismo código hash para dos objetos tienen el mismo contenido, por ejemplo

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }   
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

Salida:

true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
false
employee2.hashCode(): 128107556

La implementación de hashCodedados anteriormente produce el mismo código hash para employee1y employee2a pesar de que equalslos rendimientos false(cheque como el punto # 3 mencionado anteriormente de la documentación).

A manera incorrecta de anular de hashCodepuede resultar incluso en los mismos objetos que regresan diferentes hashcodes por ejemplo,

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : (int) (code.length() * (Math.random() * 100)));
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee1.hashCode() again: " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

Salida:

true
employee1.hashCode(): 66066760
employee1.hashCode() again: 66069457
employee3.hashCode(): 66073797
false
employee2.hashCode(): 66074882

Esta es la manera incorrecta de anular hashCodedebido a invocar hashCodeen el mismo objeto más de una vez durante una ejecución de una aplicación Java tiene que volver constantemente el mismo entero (cheque como el punto # 1 mencionado anteriormente a partir de la documentación).

Ahora, mira el siguiente código y su salida:

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyEmployee other = (MyEmployee) obj;
        if (code == null) {
            if (other.code != null)
                return false;
        } else if (!code.equals(other.code))
            return false;
        return true;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

Salida:

true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
true
employee2.hashCode(): 1297685781

Desde employee1.equals(employee2)rendimientos true, el código hash también debe ser devuelto mismo (comprobación de punto # 2 se ha mencionado anteriormente de la documentación). Sin embargo, los valores hashcode de employee1y employee2son diferentes que no es correcto. Esta diferencia se debe a que no hemos anulado el hashCodemétodo. Por lo tanto, cada vez que se reemplaza equals, también se debe anular hashCodede forma correcta.

Por último, se da a continuación es una forma correcta de poner en práctica hashCodey equals:

class MyEmployee {
    String code;
    String name;
    int age;

    public MyEmployee(String code, String name, int age) {
        super();
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((code == null) ? 0 : code.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyEmployee other = (MyEmployee) obj;
        if (age != other.age)
            return false;
        if (code == null) {
            if (other.code != null)
                return false;
        } else if (!code.equals(other.code))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

public class Main {
    public static void main(String[] args) {
        MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
        MyEmployee employee3 = employee1;
        System.out.println(employee1.equals(employee3));
        System.out.println("employee1.hashCode(): " + employee1.hashCode());
        System.out.println("employee3.hashCode(): " + employee3.hashCode());
        System.out.println(employee1.equals(employee2));
        System.out.println("employee2.hashCode(): " + employee2.hashCode());
    }
}

Salida:

true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
true
employee2.hashCode(): 128107556

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=282378&siteId=1
Recomendado
Clasificación