2015-04-30 4 views
2

У меня есть список объектов, которые мне нужно добавить в HashSet, скажем List<Node> books. Скажем далее, что никакие две книги не равны в том смысле, что их метод equals будет возвращать false; скажем, однако, что их метод hashCode возвращает 1. Я использую этот крайний случай, чтобы я мог полностью понять, как работает прием. Поэтому мой вопрос таков: будет ли HashSet признавать все мои объекты?Как hashSet допускает элементы

public class Book{ 
    ... 
    @Override 
    public boolean equals(Book other){ 
    return false; 
    } 

    @Override 
    public int hashCode(){ 
    return 1; 
    } 
} 

Напомним, что hashSet не допускает дубликатов.

Мне интересно, потому что по самому имени hashSet использует хэш объекта. Является ли этот хэш случайностью, связанной с хэш-кодом добавляемого объекта?

И да я aware of

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

Но как хэш-код объекта связан с его хэш-значением в HashSet?

+0

Возможный дубликат [Hashcode и Equals for Hashset] (http://stackoverflow.com/questions/5396939/hashcode-and-equals-for-hashset) – user1717259

ответ

3

A Set состоит из ковшей для ускорения поиска. Когда новый объект добавляется к Set, его хэш оценивается с использованием метода объекта hashCode().

Затем, на основе этого хэш, то Set решает, какое ведро объект должен быть сохранен в.

Затем, когда вы ищете объект внутри этого Set (используя, например метода), то хэш снова оценивается, а затем Set выполняет итерацию по всем элементам в одном ведре (вместо итерации по всем элементам Set). Это делает его намного быстрее, потому что - обычно - установленные элементы распределяются (более или менее) одинаково среди многих ковшей.

В вашем случае все объекты будут храниться в одном ведре, поэтому ваш Set не будет работать по-другому (с точки зрения производительности), чем List.

И, отвечая на исходный вопрос: Да, он будет хранить все ваши объекты так долго, как их equals() будет реализован правильно.

0

Я немного смущен вашим вопросом. HashSet будет использовать метод hashCode() добавляемого элемента (List<Node> books в этом случае). Поэтому, если вы добавите List, HashSet вызовет hashCode на List, а не на Book, если вы не добавите элементы Book отдельно. Если вы добавите их по отдельности, это вызвало то, что вы определили в своем вопросе hashCode().

В качестве побочного примечания никогда не возвращайте постоянное значение в hashCode(). См. Best implementation for hashCode method

Смежные вопросы