![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: 4 Всего: 12 |
Вот, решил что хватит по верхушкам бродить. Не стыжусь спросить.
Копнул, и выяснилось что я до конца не понимаю смысла хеш-кода у Object и правила его формирования. Хелп: The general contract of hashCode is: -Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. т.е. если я создаю экземпляры некоего класса как и все, расширяющего Object - то у 2-х моих экземпляров хеш-код может быть одинаков? -If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. т.е. 2 одинаковых объекта имеют один хеш-код. тут понятно. но не до конца понятно - что есть 2 именно одинаковых объекта. т.е. TTst a,b; a=new TTst; b=new TTst; a.equals(b) - true или false? а после a.prop1=1; b.prop1=2; a.equals(b) - true или false? т.к. про equals написано: ========== The equals() method compares two objects of the same type for equality by comparing the properties of both objects. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It simply returns a boolean value depending on the results of the object that calls it and the object that is passed to it. For instance, if equals() is called by an object that passes it an object that is identical, the equals() method returns a true value ============= -It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables тут говорят что если a.euals(b)==false - то хешкод у a и b - разный. так? что-то я запутался. поставте обратно меня на рельсы, а? Спасибо! -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| Domestic Cat |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Да.
Это два объекта, для которых equals возвращает true.
Да. Если вкратце: equals ДОЛЖЕН ПО ИДЕЕ возвращать true если оба объекта одинаковы по свойствам. Но по умолчанию, если его не переопределить, он возвратит то же, что и ==. А == сравнивает ссылки, и возвращает тру если обе ссылки ссылаются на один объект. equals ты можешь определять как угодно, по равенству всех полей, или некоторых полей. Хеш код нужен для хешмапов, хештейблов, хешсетов. Он ничего не значит, просто придуман для того, чтобы хеш-коллекции были эффективными. Потому он и определен так, как ты процитировал: если два объекта равны через equals, они обязаны иметь один хешкод, но равенство хешкодов не означает равенства через equals. -------------------- |
||||||
|
|||||||
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: 4 Всего: 12 |
Большое СПАСИБО!
-------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| hatsumeika |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.5.2005 Где: Минск Репутация: 2 Всего: 2 |
Если hashCode не переопределить, то нельзя будет класс использовать в HashMap, HashSet и т.п. в качестве ключей. Потому что они сначала ищут по hashCode, а только потом по equals.
Не будет ничего страшного если реализовать hashCode() как return 13; Конечно в HashMap, HashSet все сведется к полному перебору. Отсюда следствие: hashCode должен просто обеспечивать какой-то разброс значений для разных объектов, поэтому лучше использовать какое-то сравнительно уникальное поле и возвращать его hashCode |
|||
|
||||
| Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Неверно, использовать можно будет, а метод hashCode() будет вызываться унаследованный от Object. -------------------- |
|||
|
||||
| hatsumeika |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.5.2005 Где: Минск Репутация: 2 Всего: 2 |
формально использовать можно, только работать будет мягко говоря специфически:
вот этот код напечатает null, а не "ASD"
|
|||
|
||||
| Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Ну тогда и equals нужен. -------------------- |
|||
|
||||
| hatsumeika |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.5.2005 Где: Минск Репутация: 2 Всего: 2 |
да, Блох рекомендует equals and hashCode переопределять вместе
|
|||
|
||||
| Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Да нет, без него тоже будет нул давать. -------------------- |
|||
|
||||
| hatsumeika |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.5.2005 Где: Минск Репутация: 2 Всего: 2 |
согласен. надо обоих переопределять.
|
|||
|
||||
| Sleepy_PIP |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: 4 Всего: 12 |
как это, как это! - как я где-то читал (сорри, не помню где) - родной Object.hashCode пользует для построения хеш-кода в т.ч. и "адрес" объекта (ссылки) - так что довольно уникален ... а? -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
|||
|
||||
| Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Он для разных объектов даст разные значения, независимо от того, equals они или нет. Например new Integer(2) и new Integer(2) будут иметь различный хешкод. -------------------- |
|||
|
||||
| Sleepy_PIP |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 512 Регистрация: 30.6.2004 Где: Moscow Репутация: 4 Всего: 12 |
хм ... опять .. оптяь не понисмаю. MyClass a,b; a=new MyClass(); b=new MyClass(); что тут даст hashCode и a.equal(b) а теперь a.Prop1=2; b.Prop1=3; что тут даст hashCode и a.equal(b) ??? и на чем это основано? по докам - equal - во втором случае дас false т.к. поля класса изменены ... не так? -------------------- -- Sleepy_PIP. Pavel Pryazhentsev (ex. 2:5020/141) "... Лучше быть нужным, чем свободным ..." |
||||
|
|||||
| hatsumeika |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.5.2005 Где: Минск Репутация: 2 Всего: 2 |
если в MyClass не переопределены equals() и hashCode(), то исп. соотв. методы у Object, поэтому a.equals(b) всегда будет false.
Если переопределены, то зависит проверяется ли поле Prop1. Короче создатель класса определяет, что такое для этого класса equals. Например извращение: класс, объекты которого никогда ничему не равны, даже сами себе:
Это сообщение отредактировал(а) hatsumeika - 16.5.2005, 18:45 |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Эти будут иметь один. "To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method." Вообще надо поискать информацию по хэш-функциям - для чего они. Там более подробно можно почитать. Идея в том, чтобы ускорить выборку для очень сложных объектов, которые просто сравнивать между собой очень неудобно. А хэш-функция вычисляется обычно очень быстро и для каких-то данных она уникальна для набора каких-то ключевых полей. Например для тех же String, Integer, Double и прочая. Если я имею класс, который хочу использовать в качестве ключа в Hashtable, то если я хочу, чтобы при равенстве какого-то набора полей я думал, что это один и тот же ключ, то я должне написать hashCode() который такое и сделает. Если брать практический пример, то в той же Hashtable ключ используется имеено в разрезе hashCode. Т.е. если я знаю, что в моей Hastable есть ключ Integer(1) и ему соответствует "Старая строка", то операция put(Integer(1), "Новая строка") заменит строку в таблице. А не прибавит новую. |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |