Подтвердить что ты не робот

Java - TreeSet и hashCode()

У меня есть быстрый вопрос о TreeSet коллекциях и hashCode. У меня есть TreeSet, и я добавляю к нему объекты, прежде чем добавить объект, я проверяю, существует ли он в TreeSet с помощью contains.

У меня есть два разных объекта, каждый из которых создает отдельный хэш-код, используя мою реализацию метода hashCode, пример ниже:

public int hashCode()
{
    int hash = 7;
    hash = hash * 31 + anAttribute.hashCode();
    hash = hash * 31 + anotherAttribute.hashCode();
    hash = hash * 31 + yetAnotherAttribute.hashCode();
    return hash;
}

Хэш-коды для конкретного прогона: 76126352 и 76126353 (объекты различаются только одной цифрой в одном атрибуте).

Метод contains возвращает true для этих объектов, хотя хэш-коды отличаются. Любые идеи почему? Это действительно запутывает, и помощь действительно будет оценена.

4b9b3361

Ответ 1

TreeSet вообще не использует hashCode. Он использует либо compareTo, либо Компаратор, который вы передали конструктору. Это используется методами типа contains для поиска объектов в наборе.

Итак, ответ на ваш вопрос заключается в том, что ваш метод compareTo или ваш Comparator определены так, что два объекта, о которых идет речь, считаются равными.

Из javadocs:

экземпляр TreeSet выполняет все сравнения элементов с использованием compareTo (или сравнить), так что два элементы, которые считаются равными метода, с точки зрения set, equal.

Ответ 2

Из Java Doc:

Если два объекта равны в соответствии с методом equals (Object)     то вызов метода hashCode на каждом из двух объектов должен     производят одинаковый целочисленный результат.

Значит: объекты, которые вы используете для хэширования, не равны.

Ответ 3

Вам нужно прочитать главу 3 "Эффективная Java" Джошуа Блоха. Она объясняет контракт на равный и как правильно переопределять равные, hashCode и compareTo.

Ответ 4

Вам не нужно проверять, содержится ли он, потому что вставка() в основном выполняет ту же операцию (т.е. ищет правильную позицию) на пути к точке вставки. Если объект не может быть вставлен (т.е. Объект уже содержится), insert возвращает false.