Предисловие
Как мы все знаем, java.lang.object имеет метод HashCode () и Equals (), который играет важную роль в дизайне программного обеспечения. Перепишите эти два метода в некоторых классах, чтобы выполнить некоторые важные функции.
1. Зачем использовать HashCode ()?
Элементы в наборе набора являются неупорядоченными и неповторимыми. Итак, в чем основание для оценки того, повторяются ли два элемента?
Некоторые люди говорят: Object.equal() , конечно, используется для сравнения, равны ли объекты. Тем не менее, в наборе существует большое количество объектов, и количество сравнений элементов объекта, добавленных в набор, будет постепенно увеличиваться, что значительно снижает эффективность работы программы. Java использует алгоритм хеширования (также называемый алгоритмом хэширования) для решения этой проблемы. Объект (или данные) напрямую отображается по адресу в соответствии с конкретным алгоритмом, и эффективность доступа объекта значительно улучшается.
Таким образом, когда набор, содержащий большое количество элементов, необходимо добавить элемент (объект), сначала вызовите HashCode () этого элемента, и вы можете расположить фактическое место хранения этого элемента одновременно. Если в этой позиции нет элемента, это означает, что этот объект хранится в сборе, установленном в первый раз, и объект хранится непосредственно в этой позиции; Если в этой позиции есть объект, вызовите Eart (), чтобы увидеть, равны ли два объекта. Если то же самое верно, отбросьте элемент и не существует. Если это не равное, хеши с другими адресами.
Это также причина, по которой установленная набор хранит данные типа объекта, необходимо не только переписать метод hashcode () объекта, но и переписать метод equals ().
2. Как использовать HashCode ()?
Взаимосвязь между возвратом значения HashCode () и Equals ()
Вот пример. В реальной разработке программного обеспечения лучше всего переписать эти два метода.
Сотрудник открытого класса {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 (); вернуть хэш; }}Методы equals () и hashcode () используются для сравнения в том же классе, особенно при хранении одного и того же объекта класса в контейнере, таких как установка для хранения объектов в одном классе.
Здесь нам сначала нужно понять проблему:
Два объекта с равным () равны, hashcode () должен быть равным, а два объекта с равным () не равны, не могут доказать, что их Hashcode () не равны. Другими словами, для двух объектов, чей равенственный () метод не является одинаковым, hashcode () может быть равным.
Здесь HashCode похож на индекс каждого символа в словаре, и Equals () похоже на сравнение разных слов под одним и тем же символом в словаре. Как и в словаре, поиск двух слов «я» и «спонтанно» под словом «я» в словаре, если Equals () используется для определения равенства слова запроса, это то же самое слово. Например, два слова, сравниваемые по равным (), являются «самостоятельно», тогда значения, полученные с помощью метода hashcode (), должны быть равны в настоящее время; Если метод equals () сравнивает слова «я» и «спонтанно», то результат заключается в том, что вы не хотите ждать, но оба эти слова принадлежат словам «я», и поэтому при поиске индексов, то есть hashcode () одинаково. Если Equals () сравнивает слова «self» и «они», то результаты также различны, а результаты, полученные HashCode (), также различаются в настоящее время.
И наоборот: hashcode () отличается, и Equals () может быть введен; HashCode () равен, Equals () может быть равным или не может быть равным.
В классе объекта метод hashcode () является локальным методом, который возвращает значение адреса объекта. Метод equals () в классе объекта также сравнивает значения адреса двух объектов. Если equals () равно, это означает, что значения адреса двух объектов также равны. Конечно, HashCode () равна.
Поскольку равные более точны для сравнения равных элементов, зачем использовать метод HashCode ()?
Поскольку алгоритм хэш обеспечивает высокую эффективность в поиске элементов, если вы хотите найти, содержит ли коллекция объект, как написать приблизительный код программы?
Вы обычно вынимаете каждый элемент один за другим, чтобы сравнить с объектом, который вы ищете. Когда вы обнаружите, что результат сравнения метода равных между элементом и объектом, который вы ищете, прекратите поиск и возвращайте положительную информацию. В противном случае вернуть негативную информацию. Если в коллекции есть много элементов, таких как 10 000 элементов, и не содержат объект, который вы ищете, это означает, что вашей программе необходимо взять 10 000 элементов из коллекции и сравнить один за другим, чтобы сделать вывод.
Класс объекта определяет метод hashcode () для возврата хеш -кода каждого объекта Java. При поиске объекта из коллекции хэшса система Java сначала вызывает метод HashCode () объекта для получения хэш -кодовой таблицы объекта, а затем находит соответствующую область хранения на основе хэша и, наконец, получает каждый элемент в области хранения и сравнивает его с объектом для равных. Таким образом, вы можете сделать вывод, не пройдя все элементы в коллекции. Видно, что коллекция хэшсет имеет хорошую производительность поиска объектов.
Тем не менее, эффективность хранения объектов в сборе хэшса является относительно низкой, поскольку при добавлении объекта в сбору хешса хэш -код объекта должен быть рассчитан сначала, а местоположение объекта в сборе определяется на основе этого хэш -кода. Чтобы убедиться, что объекты экземпляра класса могут храниться нормально в хэшсете, результаты двух объектов экземпляра этого класса должны быть равны по сравнению с методом equals () равны; То есть, если результат obj1.equals(obj2) является истинным, то результат следующего выражения также должно быть true:obj1.hashCode() == obj2.hashCode() .
Другими словами: когда мы переписываем метод равных объекта, мы должны переписать его метод хэшкода. Если мы не переписываем его метод хэшкода, метод хэшкода в объекте объекта всегда возвращает хэш -адрес объекта, и этот адрес никогда не бывает равным. Таким образом, даже если метод Equals переписан в настоящее время, не будет никакого специфического эффекта, потому что, если метод хэшкода не хочет ждать, он не будет вызывать метод равных для сравнения, поэтому он бессмыслен.
Большинство структур данных используют метод Equals, чтобы определить, содержат ли они элемент, например:
List <string> list = arrays.aslist ("a", "b", "c"); boolean содержит = list.contains ("b"); Эта переменная содержит результат, верно, потому что, хотя «B» - это разные случаи (кроме того, резиденция строки игнорируется), они равны.
Они используют быстрый способ сравнения (уменьшить равенство потенциального экземпляра) вместо сравнения каждого элемента, содержащегося в экземпляре. Быстрое сравнение требует только сравнения следующих аспектов:
Сравнение ярлыков означает, что, сравнивая значения хэша, оно может заменить экземпляр на целочисленное значение. Экземпляры с одним и тем же хэш -кодом не обязательно равны, но экземпляры с равенством должны иметь одинаковое значение хэша. (или должно быть, мы скоро обсудим это) Эти структуры данных часто названы этой техникой, и они могут быть идентифицированы Hash, среди которых HashMap является наиболее известным представителем.
Они обычно работают так:
При добавлении элемента его хэш-код используется для расчета индекса внутренней массивы (то есть так называемое ведро)
Если да, неравные элементы имеют один и тот же хэш -код, они в конечном итоге оказываются на одном и том же ведре и объединены вместе, например, добавив в список.
Когда выполняет экземпляр, содержит операции, его хэш -код будет использоваться для расчета значения ведра (значение индекса), и экземпляр будет сравниваться только тогда, когда элементы существуют в соответствующем значении индекса.
Поэтому равные, HashCode определяется в классе объекта.
Если HashCode используется в качестве ярлыка для определения равенства, то есть только одна вещь, о которой мы должны заботиться: равные объекты должны иметь одинаковый хэшкод, поэтому, если мы переопределим метод Equals, мы должны создать реализацию хэшкода, которая соответствует ей!
В противном случае равные объекты могут не иметь такого же хэш -кода, потому что они будут вызывать реализацию объектов по умолчанию.
Цитата из официальных документов
Генеральная конвенция HashCode:
При вызове того же объекта, работающего в приложении Java, метод хэшкода всегда должен возвращать одно и то же целое число. Это целое число не должно быть последовательным в разных приложениях Java. В соответствии с методом equals(Object) , если два объекта равны, два объекта вызывают метод хэшкода, должны давать один и тот же результат.
Согласно методу equals(Object) , если два объекта не равны, то вызов метода HashCode не обязательно дает различные целые результаты. Тем не менее, программисты должны понимать, что получение различных целых результатов для неравных объектов, вероятно, улучшит производительность хэш -таблицы.
Реализация хэшкода
Вот простая реализация person.hashcode() :
@OverridePublic int hashcode () {return objects.hash (firstname, lastname);}Человек рассчитывает хэш -код, объединяя несколько полей. Все они рассчитаны по функции хэш объекта.
Выберите поле
Но какие поля связаны? Требования помогут нам ответить на этот вопрос:
Если равный объект должен иметь один и тот же хэш -код, вычислимый хеш -код не должен включать никаких полей, которые не используются для проверки равенства. (В противном случае эти два объекта просто в том, что эти поля разные, но они все еще могут быть равными, но в настоящее время хэш -коды двух объектов будут разными.) Таким образом, подмножество полей, используемых, когда поля хеш -группы должны быть равными. Те же поля используются по умолчанию, но есть некоторые детали, которые нужно рассмотреть.
Суммировать
Мы понимаем, что вычисление хэш -кода состоит в том, чтобы сжать равное целочисленное значение: равные объекты должны иметь тот же хэш -код, и для соображений производительности лучше всего использовать один и тот же хэш -код, как можно меньше, как возможные неравные объекты.
Это означает, что если метод равных переписан, то метод хэшкода должен быть переписан.
При реализации HashCode использует те же поля, которые используются в равных (или подмножество полей, используемых в равных)
Лучше всего не включать изменяемые поля. Не рассматривайте о том, чтобы вызовать HashCode для коллекций. Если нет специального входного режима, попробуйте использовать общий алгоритм хэш -хэш.
Хорошо, вышеупомянутое содержимое этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.