|
|
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
в HashSet элементы добавляются на основе хеш-кода. допустим, я написал хеш-функцию, которая учитывает значение всех полей. положил в множество объект. потом у объекта поменял одно из полей, и положил объект еще раз. получается, что в множестве появился один и тот же объект 2 раза!!!! вопрос: это так и должно быть? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 11:05 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
А при чем здесь баг или фича? HashSet хранит ссылки на объекты, объект поменял свое состояние(новый hashcode) - и был добавлен. Все правильно. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 11:49 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
в итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 11:52 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deadyв итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну. дай определение почитать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 11:52 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
определение чего? короче, придумал 2 варианта: 1. это баг. связан с тем, что contains проверяет объекты только в одной ячейке (ячейка - это остаток от деления хеш-кода на число ячеек). а должен бы во всех. 2. фича. данный объект HashSet подходит только для хранения объектов типа Immutable или тех, у кого не переопределен метод hashSet. Для них более подходит IdentityHashSet ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 11:59 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deadyопределение чего?а ты про несколько определений говорил? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:00 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
определение интерфейса Set: A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction. ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:01 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deadyопределение интерфейса Set: A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction. и чо? есть противоречия с тем, что у тебя происходит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:02 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
А.ГрасоffT > и чо? есть противоречия с тем, что у тебя происходит? да. у меня в HashSet лежит 2 объекта, применение метода equals к которым вернет true. ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:03 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Вот что написано в документации по Object.hashCode(): 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. Ты конракт нарушаешь. После этого HashSet тебе уже ничего не должен ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:07 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deadyда. у меня в HashSet лежит 2 объекта, применение метода equals к которым вернет true. а это просто несоответствие описанию :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:10 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
читал. почему-то мне подумалось, что это правила для Object.hashCode(), не сказано, что они распространяются на пользовательские классы. Kerst The general contract of hashCode is: вывод - дока написано не идеально понятно. ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:15 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deadyвывод - дока написано не идеально понятно переходи на пэхапэ :) PS а в хэшсете используется хэшмап для хранения объектов, у которой уникальным будет объект по его хэшу, а не equals'у :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 12:20 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Рецепт в первом приближении от дяди Эккеля и Joshua Bloch [Effective Java (Addison-Wesley 2001)],для написания "правильного" :-)) хэш-кода: Ekkel, 3d Edition,Joshua Bloch,Effective Java (Addison-Wesley 2001) 1. Store some constant nonzero value, say 17, in an int variable called result. 2. For each significant field f in your object (each field taken into account by the equals method, that is), do the following: a. Compute an int hash code c for the field: i. If the field is a boolean, compute (f ? 0 : 1). ii. If the field is a byte, char, short, or int, compute (int)f. iii. If the field is a long, compute (int)(f ^ (f >>> 32)). iv. If the field is a float compute Float.floatToIntBits(f). v. If the field is a double, compute Double.doubleToLongBits(f), and then hash the resulting long as in step 2.a.iii. vi. If the field is an object reference and this class's equals method compares the field by recursively invoking equals, recursively invoke hashCode on the field. If a more complex comparison is required, compute a “canonical representation” for this field and invoke hashCode on the canonical representation. If the value of the field is null, return 0 (or some other constant, but 0 is traditional). vii. If the field is an array, treat it as if each element were a separate field. That is, compute a hash code for each significant element by applying these rules recursively, and combine these values as described in step 2.b. b. Combine the hash code c computed in step a into result as follows: result = 37*result + c; 3. Return result. 4. When you are done writing the hashCode method, ask yourself whether equal instances have equal hash codes. If not, figure out why and fix the problem. Там же есть и пример для класса PhoneNumber, Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 15:03 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
этот "правильный" хэш код - тоже неправильный, т.к. не меняет своей сути - он изменяется при изменении состояния объекта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 16:30 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Timmэтот "правильный" хэш код - тоже неправильный Для примера из книги Effective Java он как раз правильный - переменным areaCode,exchange,extension присваевается значение только из конструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 16:58 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
AlexMD Timmэтот "правильный" хэш код - тоже неправильный Для примера из книги Effective Java он как раз правильный - переменным areaCode,exchange,extension присваевается значение только из конструктора. надо договаривать :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 17:11 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Timmон изменяется при изменении состояния объекта На то и пункт номер 4 у Эккеля :-)) Согласитесь, нужно ещё анализировать и предметную область ;-)) Например, если был объект класса PhoneNumber с московским номером 555-20-25, а потом превратился :-) в екатеринбуржский номер 550-20-25 - то можно ли считать объект прежним? ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 17:18 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Timmнадо договаривать :-) Вы правы ;-) - вот кусок кода из книги: Код: plaintext 1. 2. 3. 4. 5. 6. для final переменных класса? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2005, 17:23 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
в что все накинулись на хешкод? все правильно с хешкодом надо читать жава док к Set Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element. короче это такая фича ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 11:48 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
--0 > в что все накинулись на хешкод? > все правильно с хешкодом > надо читать жава док к Set > Note: Great care must be exercised if mutable objects are used as > set elements. The behavior of a set is not specified if the value of > an object is changed in a manner that affects equals comparisons > while the object is an element in the set. A special case of this > prohibition is that it is not permissible for a set to contain > itself as an element. > короче это такая фичаТема==Ответить ну, четко сказано, что поведение не указано для объекта, который изменится так, что это повлияет на equals. а те действия на equals не влияют, потому что a.equals(a) всегда true. ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 11:54 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
AlexMDСогласитесь, нужно ещё анализировать и предметную область ;-)) Например, если был объект класса PhoneNumber с московским номером 555-20-25, а потом превратился :-) в екатеринбуржский номер 550-20-25 - то можно ли считать объект прежним? ;-) если у меня есть объект класс имплое с полем зарплата после изменения зарплаты можно ли считать объект прежним? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 11:55 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
--0 > если у меня есть объект класс имплое с полем зарплата > после изменения зарплаты можно ли считать объект прежним? конечно. это тот же объект с изменившимся состоянием. если только он не immutable ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 11:57 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
авторну, четко сказано, что поведение не указано для объекта, который изменится так, что это повлияет на equals. а те действия на equals не влияют, потому что a.equals(a) всегда true. старый а уже не иквалз новому а так что все пучком короче осторожней надо быть с мутабл объектами ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 12:00 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
--0если у меня есть объект класс имплое с полем зарплата после изменения зарплаты можно ли считать объект прежним? Конечно нужно - так ведь я о том же и писал, уважаемый. Вы только доказываете мою правоту ( и Эккеля :-)) ) В приведённом вами примере для объекта класса Имплое хэш-код можно рассчитывать с помощью переменной класса ИНН или SSN - смотря какой страны вы налогоплательщик ;-))) Если же менять челу SSN (а насколько я знаю, он присваивается только один раз) - то получаем нового налогоплательщика по программе ФБР о защите свидетелей ;-)). Так что AlexMDнужно ещё анализировать и предметную область ;-)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 12:35 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
AlexMD умно... предметная область... если я добавляю в эрейлист ещё один элемент могу ли я считать этот эрейлист прежним? простите дурака, но я абсолютно не втыкаю в то, что вы тут наговорили ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 12:56 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
--0 > если я добавляю в эрейлист ещё один элемент могу ли я считать этот эрейлист прежним? если вы скушаете завтрак, вы можете себя считать прежним? или вы после этого - не вы? ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 13:05 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
дык вот в том то и дело и не надо тут нести о каких то ИНН и что хешкод надо стоить по имутабл каким то идентификаторам и вообще развели флуда про хешкод дяденька экель сказал только что вот мазово строить хешкод а уж как ты будешь это делать никого не волнует есть жава док к хешкоду там есть констрейнсы если они соблюдены то все пучком ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 13:40 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
А.ГрасоffT переходи на пэхапэ :) последовал совету. вчера почетал книгу. ужос! ----------------------------------- The Bat + My Gate Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 13:51 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Deady --0 > если я добавляю в эрейлист ещё один элемент могу ли я считать этот эрейлист прежним? если вы скушаете завтрак, вы можете себя считать прежним? или вы после этого - не вы? Не я. Я до завтрака - невыспавшаяся и злобная тварь, а после - белый и пушистый добряк. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2005, 15:06 |
|
||
|
HashSet: баг или фича?
|
|||
|---|---|---|---|
|
#18+
Фторой раз. Я конечно дискус до конца не дочитал. Но в Хорстмане и Корнелле это очень хорошо написано, что реализации несколько искажают спецификацию интерфейса карт и множеств. Посуди сам в интерфейсе написано equals(), а в деревянных реализациях используется compareTo(), а в хэшированных, понятно хеш. Но по другому то никак. от тебя и просят согласовывать все три метода, но как правило пишется тот который нужен для используемой коллекции. А чтобы контейнер реагировал на изменения элементов - это ваще петля, тут такая сложная структура нужна .... С хешсетом могу посоветовать перед изменением удалять, а после пихать обратно. А ещё часто к месту менее популярные классы типа LinkedHashSet, IdentityHashMap и LinkedHashMap и т.д. На засыпку вопрос: карта это множество Entry или множество это карта с нулевыми value'ями ??? См java.util.* ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2005, 05:19 |
|
||
|
|

start [/forum/topic.php?all=1&fid=59&tid=2150605]: |
0ms |
get settings: |
6ms |
get forum list: |
18ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
54ms |
get topic data: |
6ms |
get forum data: |
1ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
| others: | 220ms |
| total: | 354ms |

| 0 / 0 |
