Хэш расчет состоит в том, чтобы рассчитать, какой элемент должен быть помещен в массив. Чтобы быть точным, это положено, в каком списке ссылок. Согласно правилам Java, если вы хотите поместить объект в HashMap, класс вашего объекта должен предоставить метод хэшкода и вернуть целочисленное значение. Например, класс строки имеет следующие методы:
public int hashcode () {int h = hash; int len = count; if (h == 0 && len> 0) {int off = offset; char val [] = value; for (int i = 0; i <len; i ++) {h = 31*h+val [off ++]; } hash = h; } return h; } Обратите внимание на петлю выше, разве это не испорчено? Позвольте мне привести вам пример, чтобы легко понять, что он делает. Например, существует строка «ABCDE», которая использует 31-значный метод расчета для расчета суммы этой строки. Вы напишете следующую формулу расчета:
A*31^4+B*31^3+C*31^2+D*31^1+E*31^0. Обратите внимание, что A, B, C, D или E здесь относятся к их значениям ASCII. Очень интересные петли, которые можно использовать для расчета N-цифры. Этот цикл может быть извлечен отдельно в качестве хорошего инструмента для расчета раздела:
public static void main (string [] args) {int [] a = {1,0}; System.out.println (Рассчитайте (2, A)); } private static int Расчет (int Radix, int [] a) {int sum = 0; for (int i = 0; i <a.length; ++ i) {sum = sum*radix+a [i]; } return sum; } Статический метод Caculate принимает Radix в качестве кардинальности, и массив и моделирует количество расчета, которое будет рассчитан, просто обратите внимание на согласованное порядок поверхности. Например, двоичная строка 01 должна быть расположена в массиве в соответствии с {0,1}. Вывод выше 1, что соответствует истинному значению 01.
Так зачем использовать 31 в качестве базы? Во -первых, вам нужно понять, почему нужен хэшкод. Каждый объект вычисляет HashCode на основе значения. Хотя этот размер кода не требует уникальности (потому что это обычно будет очень медленным), он должен быть как можно больше и не повторяться, поэтому кардинальность должна быть максимально большой. Кроме того, компилятор может быть оптимизирован 31*N для сдвига влево на 5 бит, а затем снизить на 1, что имеет более высокую производительность. На самом деле, все еще спорно выбрать 31, пожалуйста, обратитесь к нему здесь.
Я думаю, что эта вещь все равно приведет к большему количеству повторений и должна использовать большие числа. Так что, возможно, в будущем могут произойти некоторые изменения в реализации Java. В следующей статье представлены два вывода:
1. Используйте основные числа для кардинальности
Характеристики первичных чисел (только 1 и сами по себе являются факторами) могут сделать результат, полученный, умножая его на другие числа проще в создании уникальности, чем другие методы, то есть вероятность конфликта между значениями хеш -кода является наименьшим.
2. Выбор 31 - выбор после наблюдения за результатами распределения. Причина не ясна, но это действительно полезно.
Кроме того, первое рассчитанное значение будет кэшировано внутри, потому что это конечный (неизбежный) класс, то есть содержание объекта строки не изменится. Это может повысить производительность при многократном положении HashMap, но, похоже, он мало используется.
Суммировать
Вышеуказанное касается причин, по которым 31 коэффициент используется при определении хэшкода. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на этот сайт:
« Подробное введение в переписывание методов HashCode () и equals () »
« Подробное объяснение основных различий и связи между HashCode () и Equals () »
« Анализ исходного кода Java использования HashMap »
Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!