powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / HashSet: баг или фича?
25 сообщений из 32, страница 1 из 2
HashSet: баг или фича?
    #33445934
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в 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
HashSet: баг или фича?
    #33446072
rikman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А при чем здесь баг или фича? HashSet хранит ссылки на объекты, объект поменял свое состояние(новый hashcode) - и был добавлен. Все правильно. :-)
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33446079
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну.
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33446081
Фотография А.Грасоff™
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Deadyв итоге хеш код хранит 2 одинаковые ссылки на один и тот же объект. хотя по определению должен хранить только одну.
дай определение почитать.
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33446110
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
определение чего?


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

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

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

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



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

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


Kerst
The general contract of hashCode is:


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

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

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

PS а в хэшсете используется хэшмап для хранения объектов, у которой
уникальным будет объект по его хэшу, а не equals'у :)
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33446874
AlexMD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рецепт в первом приближении от
дяди Эккеля и 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
HashSet: баг или фича?
    #33447186
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
этот "правильный" хэш код - тоже неправильный, т.к. не меняет своей сути - он изменяется при изменении состояния объекта.
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33447262
AlexMD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timmэтот "правильный" хэш код - тоже неправильный
Для примера из книги Effective Java он как раз правильный -
переменным areaCode,exchange,extension присваевается значение только
из конструктора.
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33447298
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexMD Timmэтот "правильный" хэш код - тоже неправильный
Для примера из книги Effective Java он как раз правильный -
переменным areaCode,exchange,extension присваевается значение только
из конструктора.
надо договаривать :-)
...
Рейтинг: 0 / 0
HashSet: баг или фича?
    #33447328
AlexMD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timmон изменяется при изменении состояния объекта
На то и пункт номер 4 у Эккеля :-))

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

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


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


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

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


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

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


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


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