Java - набор деревьев и хэш-код()
Вопрос
У меня есть небольшой вопрос о TreeSet
коллекции и hashCode
методы.У меня есть TreeSet
и я добавляю к нему объекты, прежде чем добавить объект, я проверяю, существует ли он в TreeSet
используя contains
способ.
У меня есть 2 разных объекта, каждый из которых создает отдельный хэш-код, используя мою реализацию метода 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 для этих объектов, даже несмотря на то, что хэш-коды разные.Есть какие-нибудь идеи, почему?Это действительно сбивает с толку, и мы действительно были бы признательны за помощь.
Решение
TreeSet не использует hashCode
вообще.Он использует либо compareTo
или Компаратор, который вы передали конструктору.Это используется такими методами, как contains, для поиска объектов в наборе.
Итак, ответ на ваш вопрос заключается в том, что ваш метод compareTo или ваш компаратор определены таким образом, что два рассматриваемых объекта считаются равными.
Из javadocs:
экземпляр TreeSet выполняет все сравнения элементов, используя свой метод compareTo (или compare), поэтому два элемента, которые считаются равными с помощью этого метода, с точки зрения набора равны.
Другие советы
Из Java Doc:
Если два объекта равны в соответствии с методом equals(Object), тогда вызов метода hashCode для каждого из двух объектов должен выдавать один и тот же целочисленный результат.
Означает:объекты, которые вы используете для хеширования, не равны.
Вам нужно прочитать главу 3 Джошуа Блоха "Эффективная Java".В нем объясняется контракт equals и как правильно переопределить equals, hashCode и compareTo.
Вам не нужно проверять, содержится ли он, потому что insert() в основном выполняет ту же операцию (т.е.поиск правильного положения) на пути к точке вставки.Если объект не может быть вставлен (т. Е. Объект уже содержится), insert возвращает false.