В общем, не стоит слишком сильно беспокоиться о хеш-функциях стандартных классов JDK. Даже если вы можете переопределить String (вы не можете), на практике это хеш-функция практически всегда «достаточно хороша». Есть, возможно, несколько исключений, например некоторые классы, такие как BigInteger и коллекции, каждый раз вычисляют свой хэш-код, циклически просматривая каждый элемент, который они содержат, что в некоторых случаях довольно неестественно, но как часто вы используете ключи для этих классов?
Для разработки хеш-кодов для ваших собственных классов вы пытаетесь распределить хэш-коды "случайным образом" по диапазону целых чисел. Для этого вам, как правило, нужно «смешать» биты последовательных полей в вашем объекте (вас может заинтересовать статья на моем веб-сайте, на которой графически показано , как хеш-код String смешивает биты ). Умножение текущего хэша на нечетное число (и, как правило, простое число), а затем добавление в хэш следующего элемента, как правило, работает достаточно хорошо в качестве первой попытки. (Однако с этим методом могут возникнуть проблемы, когда, например, объединяемые числа / хэш-коды имеют тенденцию иметь нули в своих младших битах - обычно нет практической хэш-функции, которая абсолютно гарантированно будет работать во всех случаях.)
Затем вы можете рассмотреть возможность проверки вашего хеш-кода. Создайте серию случайных объектов (или даже используйте некоторые реальные), вычислите их хеш-коды И, снизу, скажем, 16 битов хеш-кодов, а затем посмотрите, сколько коллизий вы получите. Убедитесь, что количество получаемых вами коллизий примерно соответствует количеству коллизий хешей, которое вы ожидаете получить случайно . Например, если вы взяли И из нижних 16 бит хеш-кода (& 0xffff), то после 1000 случайных объектов вы ожидаете около 8 коллизий. После 2000 года вы ожидаете около 30 столкновений.
Что касается производительности, то, до некоторой степени, я думаю, что получение хорошо распределенного хеш-кода в настоящее время, как правило, более выгодно, чем снижение качества хеша для скорости вычисления хеша.