Когда класс в Java не переопределяет hashCode () , печать экземпляра этого класса дает хороший уникальный номер.
Javadoc объекта говорит о hashCode () :
Насколько это целесообразно, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов.
Но когда класс переопределяет hashCode () , как я могу получить его уникальный номер?
Ответы:
System.identityHashCode (yourObject) выдаст «оригинальный» хеш-код вашего объекта в виде целого числа. Уникальность не обязательно гарантирована. Реализация Sun JVM даст вам значение, которое связано с исходным адресом памяти для этого объекта, но это деталь реализации, и вам не следует полагаться на нее.
РЕДАКТИРОВАТЬ: Ответ изменен после комментария Тома ниже re. адреса памяти и движущиеся объекты.
источник
System.identityHashCode()
?Javadoc для объекта указывает, что
Если класс переопределяет hashCode, это означает, что он хочет сгенерировать определенный идентификатор, который будет (можно надеяться) иметь правильное поведение.
Вы можете использовать System.identityHashCode, чтобы получить этот идентификатор для любого класса.
источник
hashCode()
Метод не для предоставления уникального идентификатора для объекта. Он скорее переваривает состояние объекта (то есть значения полей-членов) в одно целое число. Это значение в основном используется некоторыми структурами данных на основе хеша, такими как карты и наборы, для эффективного хранения и извлечения объектов.Если вам нужен идентификатор для ваших объектов, я рекомендую вам добавить собственный метод вместо переопределения
hashCode
. Для этого вы можете создать базовый интерфейс (или абстрактный класс), как показано ниже.Пример использования:
источник
Может быть, это быстрое, грязное решение подойдет?
Это также дает номер экземпляра класса, который инициализируется.
источник
System.identityHashCode
это лучшее решениеAtomicLong
как в этом ответе .Если это класс, который вы можете изменить, вы можете объявить переменную класса
static java.util.concurrent.atomic.AtomicInteger nextInstanceId
. (Вы должны будете дать ему начальное значение очевидным способом.) Затем объявите переменную экземпляраint instanceId = nextInstanceId.getAndIncrement()
.источник
Я пришел с этим решением, которое работает в моем случае, когда у меня есть объекты, созданные в нескольких потоках и сериализуемые:
источник
Если вы смотрите на
hashcode
типы Java, когда вы делаете.toString()
объект, базовый код выглядит так:источник
Просто чтобы дополнить другие ответы под другим углом.
Если вы хотите повторно использовать хэш-коды из «выше» и получать новые, используя неизменяемое состояние вашего класса, тогда вызов super будет работать. Хотя это может / не может каскадно доходить до Object (т.е. некоторые предки могут не вызывать super), это позволит вам получить хеш-коды путем повторного использования.
источник
Существует разница между возвращаемыми значениями hashCode () и identityHashCode (). Возможно, что для двух неравных (протестированных с ==) объектов o1, o2 hashCode () может быть одинаковым. Посмотрите пример ниже, как это правда.
источник
У меня была та же проблема, и я не был удовлетворен ни одним из ответов до сих пор, так как ни один из них не гарантировал уникальные идентификаторы.
Я тоже хотел напечатать идентификаторы объектов для отладки. Я знал, что должен быть какой-то способ сделать это, потому что в отладчике Eclipse он определяет уникальные идентификаторы для каждого объекта.
Я придумал решение, основанное на том факте, что оператор "==" для объектов возвращает значение true, только если два объекта на самом деле являются одним и тем же экземпляром.
Я считаю, что это должно обеспечить уникальные идентификаторы на протяжении всей жизни программы. Обратите внимание, однако, что вы, вероятно, не хотите использовать это в производственном приложении, потому что оно поддерживает ссылки на все объекты, для которых вы генерируете идентификаторы. Это означает, что любые объекты, для которых вы создаете ID, никогда не будут собираться мусором.
Так как я использую это в целях отладки, я не слишком обеспокоен освобождением памяти.
Вы можете изменить это, чтобы разрешить очистку Объектов или удаление отдельных объектов, если освобождение памяти является проблемой.
источник