¿Por qué HashSet permite elementos iguales si los códigos hash son diferentes?

losHashSet clase tiene unañadir (Objeto o) Método, que no se hereda de otra clase. El Javadoc para ese método dice lo siguiente:

Agrega el elemento especificado a este conjunto si aún no está presente. Más formalmente, agrega el elemento especificado.e a este conjunto si este conjunto no contiene ningún elementoe2 tal que(e==null ? e2==null : e.equals(e2)). Si este conjunto ya contiene el elemento, la llamada deja el conjunto sin cambios y devuelvefalse.

En otras palabras, si dos objetos son iguales, entonces el segundo objeto no se agregará y el HashSet seguirá siendo el mismo. Sin embargo, he descubierto que esto no es cierto si los objetose ye2 tienen diferentes hashcodes, a pesar de quee.equals(e2). Aquí hay un ejemplo simple:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;

public class BadHashCodeClass {

    /**
     * A hashcode that will randomly return an integer, so it is unlikely to be the same
     */
    @Override
    public int hashCode(){
        return new Random().nextInt();
    }

    /**
     * An equal method that will always return true
     */
    @Override
    public boolean equals(Object o){
        return true;
    }

    public static void main(String... args){
        HashSet<BadHashCodeClass> hashSet = new HashSet<>();
        BadHashCodeClass instance = new BadHashCodeClass();
        System.out.println("Instance was added: " + hashSet.add(instance));
        System.out.println("Instance was added: " + hashSet.add(instance));
        System.out.println("Elements in hashSet: " + hashSet.size());

        Iterator<BadHashCodeClass> iterator = hashSet.iterator();
        BadHashCodeClass e = iterator.next();
        BadHashCodeClass e2 = iterator.next();
        System.out.println("Element contains e and e2 such that (e==null ? e2==null : e.equals(e2)): " + (e==null ? e2==null : e.equals(e2)));
    }

Los resultados del método principal son:

Instance was added: true
Instance was added: true
Elements in hashSet: 2
Element contains e and e2 such that (e==null ? e2==null : e.equals(e2)): true

Como muestra claramente el ejemplo anterior, HashSet pudo agregar dos elementos dondee.equals(e2).

Voy a asumir que esto esno un error en Java y que de hecho hay una explicación perfectamente racional de por qué esto es así. Pero no puedo entender qué es exactamente. ¿Qué me estoy perdiendo?

Respuestas a la pregunta(5)

Su respuesta a la pregunta