Что происходит с идентификатором-хэш-кодом, когда объектов больше, чем может вместить `int`?

Метод System.identityHashCode(...) называется так, потому что он идентифицирует объекты, поэтому два разных объекта не могут иметь одинаковый идентификатор-хэш-код, верно?

Он возвращает int. Но что происходит в системе с огромным объемом оперативной памяти, когда количество объектов превышает целочисленный диапазон 2^32?

Не будет ли это проблемой для HashMap и HashSet при работе с классами, которые не переопределяют equals и hashCode?

EDIT:
Если int недостаточно, могу ли я получить настоящий уникальный идентификатор для объекта?


person java.is.for.desktop    schedule 24.07.2010    source источник
comment
~4.2*(10^9): Я предлагаю использовать простое 2^XXX, когда речь идет о чем-либо, связанном с компьютерами (т.е. 2^32 — это диапазон целых чисел).   -  person Crozin    schedule 24.07.2010
comment
@Crozin хорошо, поменял. Кстати, у меня 2^0 компьютеров, 2^1 мониторов и около 2^5 аудио-CD ;)   -  person java.is.for.desktop    schedule 24.07.2010


Ответы (3)


Нет, это будет просто обычная коллизия хешей. Допускается, чтобы два неравных объекта возвращали один и тот же хэш — просто тогда их обоих нужно будет сравнивать на равенство.

Это не ограничивается хэш-кодами идентификации — рассмотрим String.hashCode(). Очевидно, что возможных строк больше, чем значений int, поэтому должно быть хотя бы одно хеш-значение, являющееся результатом хеширования нескольких строк. HashMap/HashSet сначала использует хеш-код, чтобы быстро сузить набор возможных совпадений только до тех записей, которые имеют одинаковый хеш-код, а затем вызывает equals() для каждого по очереди, пока не найдет совпадение или не определит, что ни одно из совпадений не найдено. записей было равно заданному ключу.

person Jon Skeet    schedule 24.07.2010
comment
Спасибо! Есть ли метод Java для получения действительно уникального идентификатора объекта? Я имею в виду, что JVM может и должна уметь это делать, так почему бы не разработчику? - person java.is.for.desktop; 24.07.2010
comment
@java: Не то, чтобы я знал об этом. Соответствующий тип будет зависеть от рассматриваемой JVM, и этот идентификатор может меняться со временем, поскольку сборщик мусора перемещает его в памяти. - person Jon Skeet; 24.07.2010
comment
@Jonik: Предположим, вы хотите иметь хэш-карту, которая учитывает только идентичность объекта, а не обычное равенство - например, вы хотели хранить отдельные, но равные строки отдельно. Вы должны иметь возможность проверить подлинность объекта — это легко сделать с помощью == — но вы также должны иметь возможность получить соответствующий хэш-код. Как бы вы это сделали без identityHashCode? - person Jon Skeet; 24.07.2010
comment
@Jonik: я думаю, это достаточно ясно. По сути, это говорит о том, что если бы вы могли сделать не виртуальный вызов Object.hashCode() для этого объекта, что бы он вернул? - person Jon Skeet; 24.07.2010

Неправильный. Любое количество объектов может иметь один и тот же identityHashCode.

person user207421    schedule 24.07.2010
comment
Дополнительно: единственная гарантия заключается в том, что два объекта с разными identityHashCodes не являются одним и тем же объектом. - person Peter Lawrey; 24.07.2010

"Могу ли я получить реальный уникальный идентификатор для объекта?" Я хотел бы спросить вас, что бы вы сделали с таким идентификатором? Должен ли он быть уникальным в данный момент, в течение всего срока службы JVM или глобально в любом количестве систем?

Вы можете сгенерировать UUID для каждого объекта, для которого требуется уникальный идентификатор. Тем не менее, дубликаты идентификаторов все еще теоретически возможны, просто крайне маловероятны.

person Peter Lawrey    schedule 24.07.2010
comment
Если рассматривать в перспективе крайне маловероятно: вероятность получить 1 дубликат идентификатора при создании десятков триллионов таких идентификаторов так же велика, как падение метеорита за год (источник: Википедия). - person Bart van Heukelom; 24.09.2010
comment
Существуют некоторые типы структур данных, для которых может быть полезно иметь абсолютный сортируемый идентификатор. Например, сравнение двух переменных типа String, которые ссылаются на один и тот же экземпляр, выполняется очень быстро. Сравнение двух переменных, которые относятся к разным экземплярам и содержат одни и те же 5000 символов, выполняется медленно. Если бы можно было определить, какая строка старше, и заменить ссылку на более новый экземпляр ссылкой на более старый, действие сравнения многих строк друг с другом привело бы к консолидации совпадающих строк. - person supercat; 31.07.2013