Почему HashSet допускает равные элементы, если хэш-коды отличаются?

HashSet класс имеетдобавить (объект o) метод, который не наследуется от другого класса. Javadoc для этого метода говорит следующее:

Добавляет указанный элемент к этому набору, если его еще нет. Более формально добавляет указанный элементe к этому набору, если этот набор не содержит элементовe2 такой, что(e==null ? e2==null : e.equals(e2)), Если этот набор уже содержит элемент, вызов оставляет набор неизменным и возвращаетfalse.

Другими словами, если два объекта равны, то второй объект не будет добавлен, и HashSet останется прежним. Тем не менее, я обнаружил, что это не так, если объектыe а такжеe2 имеют разные хэш-коды, несмотря на то, чтоe.equals(e2), Вот простой пример:

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

Результаты основного метода:

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

Как ясно показывает приведенный выше пример, HashSet смог добавить два элемента, гдеe.equals(e2).

Я собираюсь предположить, что этоне ошибка в Java и что на самом деле есть совершенно рациональное объяснение, почему это так. Но я не могу понять, что именно. Что мне не хватает?

Ответы на вопрос(5)

Ваш ответ на вопрос