Я ищу решение генерировать контрольную сумму для любого типа объекта Java, который остается тем же для каждого выполнения приложения, которое производит тот же объект.
Я попробовал его Object.hashCode()
, но в API говорится
.... Эта целочисленная потребность не остается последовательной от одного выполнения приложения к другому выполнению того же приложения.
У меня была аналогичная проблема (создание хорошего хэш-кода для файлов XML), и я обнаружил, что лучшим решением является использование MD5 через MessageDigest или, если вам нужно что-то более быстрое: Fast MD5 . Обратите внимание, что даже если Object.hashCode
будет одинаковым каждый раз, он все равно будет слишком коротким (всего 32 бита) для обеспечения высокой уникальности. Я думаю, что 64 бита - это минимум для вычисления хорошего хеш-кода. Имейте в виду, что MD5 генерирует 128-битный хэш-код, что должно быть даже больше, чем необходимо в этой ситуации.
Конечно, чтобы использовать MessageDigest
, вам необходимо сначала сериализовать (в вашем случае маршал) объект.
Если вы используете Eclipse IDE, тогда у нее есть действия (в меню «Источник») для генерации хэш-кода и функции равенства. Это позволяет вам выбирать атрибуты класса, который вы хотите в хэш-коде. Это похоже на использование уже предложенного подхода HashCodeBuilder.
В качестве альтернативы вы можете передать объект в байтовый массив и сгенерировать его MD5.
Хотите ли вы сделать это для всех объектов Java?
В этом случае hashCode ()
не работает.
Для некоторых классов hashCode ()
имеет более строгое определение, которое гарантирует равенство между исполнениями. Например, String
имеет четко определенную реализацию hashCode
. Аналогично List
и Set
имеют четко определенные значения при условии, что все объекты, которые они содержат , также имеют четко определенные значения (обратите внимание, что общий Collection. hashCode ()
не требует, чтобы значение было четко определено).
Для других классов вам придется рекурсивно использовать отражение с некоторой четко определенной формулой для построения контрольной суммы.
Если вы управляете источником, вы можете реализовать hashCode (), чтобы он был согласован от одного выполнения к другому.
Библиотека общих языков Apache предоставляет класс HashCodeBuilder
, который помогает создавать хэш-код, который удовлетворяет вашим требованиям из свойств класса.
Пример:
public int checksum() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(17, 37).
append(property1).
append(property2).
append(property3).
toHashCode();
}
См. Commons Lang API
Думаю, вам стоит взглянуть на сериализацию . Механизм сериализации должен решить аналогичную проблему, поэтому вы можете посмотреть, как он реализован.
Но если вы опишете проблему, которую пытаетесь решить, вы, вероятно, получите более точное решение.
Хеш-код в порядке. Либо данное переопределение класса равно
, а также, в соответствии с требованиями контракта, хэш-код
). По контракту, если равно
, возвращается истина
хэш-код должен быть таким же.
Или класс не переопределяет равно
. В этом случае разные исполнения вашего приложения не могут создать один и тот же объект, поэтому проблем нет.
Единственная проблема заключается в том, что некоторые классы (даже из Java API) разрывают контракт для , равного
.