Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / HashSet: баг или фича? / 25 сообщений из 32, страница 1 из 2
20.12.2005, 11:05
    #33445934
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
в 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.
 import  java.util.HashSet;

 public   class  Test {
     public   static   void  main(String[] args) {
        HashSet set =  new  HashSet();
        Foo foo =  new  Foo();
        foo.setNum( 1 );
        set.add(foo);
        foo.setNum( 2 );
        set.add(foo);
        System.out.println("set = " + set);
    }


}

 class  Foo {
         private   int  num =  0 ;

         public   int  getNum() {
             return  num;
        }

         public   void  setNum( int  num) {
             this .num = num;
        }

         public   boolean  equals(Object o) {
             if  ( this  == o) {
                 return  true;
            }
             if  (o ==  null  || getClass() != o.getClass()) {
                 return  false;
            }

             final  Foo foo = (Foo) o;

             if  (num != foo.num) {
                 return  false;
            }

             return  true;
        }

         public   int  hashCode() {
             return  num;
        }
    }
...
Рейтинг: 0 / 0
20.12.2005, 11:49
    #33446072
rikman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
А при чем здесь баг или фича? HashSet хранит ссылки на объекты, объект поменял свое состояние(новый hashcode) - и был добавлен. Все правильно. :-)
...
Рейтинг: 0 / 0
20.12.2005, 11:52
    #33446079
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
в итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну.
...
Рейтинг: 0 / 0
20.12.2005, 11:52
    #33446081
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Deadyв итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну.
дай определение почитать.
...
Рейтинг: 0 / 0
20.12.2005, 11:59
    #33446110
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
определение чего?


короче, придумал 2 варианта:

1. это баг. связан с тем, что contains проверяет объекты только в одной ячейке (ячейка - это остаток от деления хеш-кода на число ячеек). а должен бы во всех.

2. фича. данный объект HashSet подходит только для хранения объектов типа Immutable или тех, у кого не переопределен метод hashSet. Для них более подходит IdentityHashSet
...
Рейтинг: 0 / 0
20.12.2005, 12:00
    #33446113
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Deadyопределение чего?а ты про несколько определений говорил? :)
...
Рейтинг: 0 / 0
20.12.2005, 12:01
    #33446117
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
определение интерфейса 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
...
Рейтинг: 0 / 0
20.12.2005, 12:02
    #33446123
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
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.
и чо? есть противоречия с тем, что у тебя происходит?
...
Рейтинг: 0 / 0
20.12.2005, 12:03
    #33446136
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
А.ГрасоffT
> и чо? есть противоречия с тем, что у тебя происходит?

да. у меня в HashSet лежит 2 объекта, применение метода equals к
которым вернет true.



-----------------------------------
The Bat + My Gate

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
20.12.2005, 12:07
    #33446148
Kerst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Вот что написано в документации по 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 тебе уже ничего не должен
...
Рейтинг: 0 / 0
20.12.2005, 12:10
    #33446165
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Deadyда. у меня в HashSet лежит 2 объекта, применение метода equals к
которым вернет true.
а это просто несоответствие описанию :)
...
Рейтинг: 0 / 0
20.12.2005, 12:15
    #33446180
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
читал. почему-то мне подумалось, что это правила для
Object.hashCode(), не сказано, что они распространяются на
пользовательские классы.


Kerst
The general contract of hashCode is:


вывод - дока написано не идеально понятно.

-----------------------------------
The Bat + My Gate

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
20.12.2005, 12:20
    #33446194
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Deadyвывод - дока написано не идеально понятно
переходи на пэхапэ :)

PS а в хэшсете используется хэшмап для хранения объектов, у которой
уникальным будет объект по его хэшу, а не equals'у :)
...
Рейтинг: 0 / 0
20.12.2005, 15:03
    #33446874
AlexMD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Рецепт в первом приближении от
дяди Эккеля и 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.
 public   int  hashCode() {
 int  result =  17 ;
result =  37 *result + areaCode;
result =  37 *result + exchange;
result =  37 *result + extension;
 return  result;
}
Где areaCode,exchange,extension - переменные класса, тип - short.
...
Рейтинг: 0 / 0
20.12.2005, 16:30
    #33447186
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
этот "правильный" хэш код - тоже неправильный, т.к. не меняет своей сути - он изменяется при изменении состояния объекта.
...
Рейтинг: 0 / 0
20.12.2005, 16:58
    #33447262
AlexMD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Timmэтот "правильный" хэш код - тоже неправильный
Для примера из книги Effective Java он как раз правильный -
переменным areaCode,exchange,extension присваевается значение только
из конструктора.
...
Рейтинг: 0 / 0
20.12.2005, 17:11
    #33447298
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
AlexMD Timmэтот "правильный" хэш код - тоже неправильный
Для примера из книги Effective Java он как раз правильный -
переменным areaCode,exchange,extension присваевается значение только
из конструктора.
надо договаривать :-)
...
Рейтинг: 0 / 0
20.12.2005, 17:18
    #33447328
AlexMD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Timmон изменяется при изменении состояния объекта
На то и пункт номер 4 у Эккеля :-))

Согласитесь, нужно ещё анализировать и предметную область ;-))
Например, если был объект класса PhoneNumber
с московским номером 555-20-25, а потом превратился :-)
в екатеринбуржский номер 550-20-25 - то можно ли считать
объект прежним? ;-)
...
Рейтинг: 0 / 0
20.12.2005, 17:23
    #33447344
AlexMD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
Timmнадо договаривать :-)
Вы правы ;-) - вот кусок кода из книги:
Код: plaintext
1.
2.
3.
4.
5.
6.
 public   final   class  PhoneNumber {
 private   final   short  areaCode;
 private   final   short  exchange;
 private   final   short  extension;
 public  PhoneNumber( int  areaCode,  int  exchange,
 int  extension) {...
Может рецепт предназначался
для final переменных класса?
...
Рейтинг: 0 / 0
21.12.2005, 11:48
    #33448722
--0
--0
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
в что все накинулись на хешкод?
все правильно с хешкодом

надо читать жава док к 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.

короче это такая фича
...
Рейтинг: 0 / 0
21.12.2005, 11:54
    #33448768
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
--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
...
Рейтинг: 0 / 0
21.12.2005, 11:55
    #33448772
--0
--0
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
AlexMDСогласитесь, нужно ещё анализировать и предметную область ;-))
Например, если был объект класса PhoneNumber
с московским номером 555-20-25, а потом превратился :-)
в екатеринбуржский номер 550-20-25 - то можно ли считать
объект прежним? ;-)


если у меня есть объект класс имплое с полем зарплата
после изменения зарплаты можно ли считать объект прежним?
...
Рейтинг: 0 / 0
21.12.2005, 11:57
    #33448782
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
--0


> если у меня есть объект класс имплое с полем зарплата
> после изменения зарплаты можно ли считать объект прежним?

конечно. это тот же объект с изменившимся состоянием. если только он
не immutable


-----------------------------------
The Bat + My Gate

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
21.12.2005, 12:00
    #33448807
--0
--0
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
авторну, четко сказано, что поведение не указано для объекта, который
изменится так, что это повлияет на equals. а те действия на equals не
влияют, потому что a.equals(a) всегда true.


старый а уже не иквалз новому а
так что все пучком
короче осторожней надо быть с мутабл объектами
...
Рейтинг: 0 / 0
21.12.2005, 12:35
    #33448944
AlexMD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
HashSet: баг или фича?
--0если у меня есть объект класс имплое с полем зарплата
после изменения зарплаты можно ли считать объект прежним?
Конечно нужно - так ведь я о том же и писал, уважаемый.
Вы только доказываете мою правоту ( и Эккеля :-)) )
В приведённом вами примере для объекта класса
Имплое хэш-код можно рассчитывать с помощью переменной
класса ИНН или SSN - смотря какой страны вы налогоплательщик ;-)))
Если же менять челу SSN (а насколько я знаю, он присваивается только один раз) - то получаем нового налогоплательщика по программе ФБР о защите
свидетелей ;-)).
Так что
AlexMDнужно ещё анализировать и предметную область ;-))
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / HashSet: баг или фича? / 25 сообщений из 32, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]