Por que o HashSet permite itens iguais se os códigos de hash forem diferentes?

oHashSet classe tem umadd (Objeto o) método, que não é herdado de outra classe. O Javadoc para esse método diz o seguinte:

Adiciona o elemento especificado a este conjunto, se ele ainda não estiver presente. Mais formalmente, adiciona o elemento especificadoe para este conjunto se este conjunto não contiver elementoe2 de tal modo que(e==null ? e2==null : e.equals(e2)). Se este conjunto já contiver o elemento, a chamada deixará o conjunto inalterado e retornaráfalse.

Em outras palavras, se dois objetos forem iguais, o segundo objeto não será adicionado e o HashSet permanecerá o mesmo. No entanto, descobri que isso não é verdade se objetose ee2 têm códigos de hash diferentes, apesar do fato de quee.equals(e2). Aqui está um exemplo simples:

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)));
    }

Os resultados do método principal são:

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 o exemplo acima mostra claramente, o HashSet conseguiu adicionar dois elementos ondee.equals(e2).

Eu vou assumir que isso énão um bug em Java e que, de fato, existe uma explicação perfeitamente racional para o porquê disso. Mas não consigo descobrir exatamente o que. o que estou perdendo?

questionAnswers(5)

yourAnswerToTheQuestion