1. Почему Hashcode ()?
Элементы в наборе набора являются неупорядоченными и неповторимыми, так что является основой для оценки того, повторяются ли два элемента? «Конечно, object.equal () используется для сравнения, равны ли объекты», - сказала определенная обезьяна. Тем не менее, в наборе существует большое количество объектов, и количество сравнений элементов объекта, добавленных в набор, будет постепенно увеличиваться, что значительно снижает эффективность работы программы. Java использует алгоритм хеширования (также называемый алгоритмом хэширования) для решения этой проблемы. Объект (или данные) напрямую отображается по адресу в соответствии с конкретным алгоритмом, и эффективность доступа объекта значительно улучшается. Таким образом, когда набор набора, содержащий большое количество элементов, необходимо добавить элемент (объект), сначала вызовите HashCode () этого элемента, и вы можете одновременно установить фактическое место хранения этого элемента. Если в этой позиции нет элемента, это означает, что объект хранится в сборе, установленном в первый раз, а объект хранится непосредственно в этой позиции; Если в этой позиции есть объект, вызовите Eart (), чтобы увидеть, равны ли два объекта. Если то же самое верно, отбросьте элемент и не существует. Если это не равное, хеши с другими адресами.
2. Как использовать HashCode ()?
Язык Java имеет пять требований, которые должны соблюдаться для равного () в дизайне обезьяны.
симметрия. Если A.Equal (b) возвращает «true», то B.Equal (a) также должен вернуть «true».
Отражающий. A.Equal (A) должен вернуть «истин».
Транзитив. Если A.Equal (b) возвращает «true» и b.equal (c) возвращает «true», то C.Equal (a) должен вернуть «true».
последовательность. Если A.Equal (b) возвращает «истинность», если содержание A и B остается неизменным, независимо от того, сколько раз A.Equal (b) должен вернуть «истинность».
В любом случае, a.equals (null) всегда возвращает «false»; a.eavals (объекты разных типов и а) всегда возвращает «false».
Взаимосвязь между возвратом значения HashCode () и Equals ().
Если A.Equals (b) возвращает «true», то HashCode () A и B должен быть равным.
Если A.Equals (b) возвращает «false», то HashCode () A и B может быть равным или может быть неравным.
Вот пример. В реальной разработке программного обеспечения лучше всего переписать эти два метода.
Сотрудник открытого класса {int employeeid; String name; // другие методы будут здесь @Override public boolean equals (Object obj) {if (obj == this) вернуть true; Сотрудник EMP = (сотрудник) OBJ; if (employeeid.equals (emp.getemployeeid ()) && name == emp.getName ()) вернуть true; вернуть ложь; } @Override public int hashcode () {int hash = 1; хэш = хэш * 17 + employeeid; hash = hash * 31 + name.hashcode (); вернуть хэш; }}3. Ниже приводится фокус на методе реализации HashCode () обычно используемых классов.
hascode () класса строки
public int hashcode () {int h = hash; if (h == 0) {int off = offset; char val [] = value; int len = count; for (int i = 0; i <len; i ++) {h = 31*h+val [off ++]; } hash = h; } return h; }Самым интересным в этом коде является метод реализации хэша. Окончательное рассчитанное значение хэша составляет:
S [0] 31N-1 + S [1] 31N-2 +… + S [N-1]
S [i]-это i-й символ строки, а n-длина строки. Тогда зачем использовать 31 здесь вместо других чисел?
31 - странный главный номер. Если множитель является равномерным числом и переполнено умножением, информация будет потеряна, поскольку умножение на 2 эквивалентно операции сдвига. Преимущества использования основных чисел не очевидны, но результаты хеш обычно используются для расчета результатов хэш. 31 имеет хорошую функцию, которая состоит в том, чтобы использовать сдвиг и вычитание вместо умножения, чтобы получить лучшую производительность: 31*i == (i << 5) -i. VMS может автоматически завершить эту оптимизацию. (Из эффективной Java)
hascode () класса объекта
HashCode () - это нативный метод в классе объекта. Как называть местные методы?
общественный родной int hashcode ();
Класс нативного метода класса объекта можно найти здесь. Пожалуйста, прочитайте еще один блог для углубленного анализа
Static jninativemethod Methods [] = {{"hashcode", "() i", (void *) & jvm_ihashcode}, {"wate", "(j) v", (void *) & jvm_monitorwait}, {"notefy", ",", void *) & jvm_monit "() V", (void *) & jvm_monitornotifyall}, {"clone", "() ljava/lang/object;", (void *) & jvm_clone},};Исходный код включает в себя getClass () (см. Line58) и т. Д. Hashcode () (см. Line43) определяется как указатель на jvm_ihashcode.
JVM.CPP определяет функцию jvm_ihashcode (строка 504). Эта функция вызывает ObjectSynchronizer :: fasthashcode, который определяется в Synchronizer.cpp. Для реализации FaSthashCode в строке 576 и GET_NEXT_HASH в строке 530 вы можете обратиться к реализации FasthashCode в строке 576 и GET_NEXT_HASH в строке 530.