Еще одна причина, по которой он реализован подобным образом, - это то, что я должен представить, что требуется, чтобы hashCode () и equals () были непротиворечивыми, а также для цели разработки Enums, чтобы они были просты в использовании и имели постоянную времени компиляции (для использовать их это "падежные" константы). Это также делает законным сравнение экземпляров enum с "==", и вы просто не хотите, чтобы "equals" вел себя иначе, чем "==" для перечислений. Это снова связывает hashCode со стандартным поведением Object.hashCode () на основе ссылок. Как было сказано ранее, я также не ожидаю, что equals () и hashCode () будут рассматривать две константы enum из разных JVM как равные. Говоря о сериализации: например, поля, типизированные как перечисления, двоичный сериализатор по умолчанию в Java имеет специальное поведение, которое сериализует только имя константы, а при десериализации ссылка на соответствующее значение перечисления в десериализационной JVM воссоздается , JAXB и другие механизмы сериализации на основе XML работают аналогичным образом. Так что: просто не волнуйся

hashCode () в классе Enum является окончательным и определен как super.hashCode (), что означает, что он возвращает число на основе адреса экземпляра, который является случайным числом от программистов POV.

Определение его, например какordinal() ^ getClass().getName().hashCode() было бы детерминированным в разных JVM. Он даже работал бы немного лучше, поскольку младшие значащие биты «изменились бы настолько, насколько это возможно», например, для перечисления, содержащего до 16 элементов, и HashMap размера 16, наверняка не было бы коллизий (конечно, использование EnumMap лучше, но иногда невозможно, например, нет ConcurrentEnumMap). С нынешним определением у вас нет такой гарантии, не так ли?

Резюме ответов

С помощьюObject.hashCode() сравнивается с более хорошим hashCode, подобным приведенному выше, следующим образом:

ПРОФИпростотаконтрасскоростьбольше коллизий (для любого размера HashMap)недетерминизм, который распространяется на другие объекты, что делает их непригодными длядетерминированные симуляцииВычисление ETagвыслеживать жуков в зависимости, например, наHashSet порядок итераций

Я лично предпочел бы более хороший hashCode, но ИМХО без причины весит много, может быть, кроме скорости.

ОБНОВИТЬ

Мне было любопытно о скорости и написалэталонный тест с удивлениемРезультаты, За цену одного поля на класс вы можете определить детерминированный хэш-код, который почтив четыре раза быстрее, Хранение хеш-кода в каждом поле будет еще быстрее, хотя и незначительно.

Объяснение того, почему стандартный хэш-код не намного быстрее, состоит в том, что он не может быть адресом объекта, поскольку объекты перемещаются GC.

ОБНОВЛЕНИЕ 2

Есть некоторые странные вещипродолжается сhashCode производительность в целом. Когда я понимаю их, все еще остается открытым вопрос, почемуSystem.identityHashCode (чтение из заголовка объекта) намного медленнее, чем доступ к полям обычного объекта.

Ответы на вопрос(7)

Ваш ответ на вопрос