Почему переопределить equals() также переопределить hashCode()
Писательские навыки у автора пока поверхностны, если что не так, укажите великодушно, буду обязательно признателен
существуетEffective Java
охвачено Разделом IXequals()
метод всегда переопределяетhashCode()
метод. Почему это? Далее мы представим эти два метода.
на Явеequals()
Методы иhashCode()
методы находятся вObject
методы в классе, тогда как в Java все классыObejct
Подкласс класса, поэтому все методы в Java будут иметь реализацию этих двух методов по умолчанию.
метод равенства
Object
в классеequals()
Метод определяется следующим образом
1public boolean equals(Object obj) {
2 return (this == obj);
3}
Мы нашлиequals()
Ключ==
,Так==
Что это означает в Java Все мы знаем, что в Java существуют базовые типы данных и ссылочные типы данных. Так==
Роль этих двух типов не одинакова.
- Примитивные типы данных: по сравнению с
==
Равны ли значения с обеих сторон? - Справочные типы данных: по сравнению с
==
Равны ли адреса памяти с обеих сторон
К основным типам данных относятся:
byte
,short
,char
,int
,long
,float
,double
,boolean
И через документацию по Javaequals()
Описание метода, все реализовать самостоятельноequals()
Метод должен соблюдать следующие правила
- Рефлексивность: для любого объекта x
x.equals(x)
должен вернутьсяtrue
- Симметрия: для любых двух объектов x и y, если
x.equals(y)
возвращениеtrue
,Такy.equals(x)
также должен вернутьсяtrue
- Транзитивность: для нескольких объектов x, y, z, если
x.equals(y)
возвращениеtrue
,y.equals(z)
возвращениеtrue
,Такy.equals(z)
также должен вернутьсяtrue
- Непротиворечивость: для двух ненулевых объектов x, y результаты, возвращаемые несколькими вызовами, должны быть одинаковыми без изменения объекта.
- Для любого ненулевого объекта x
x.equals(null)
должен вернутьсяfalse
метод hashCode
Object
серединаhashCode()
метод — это нативный метод, который возвращаетint
тип хэш-значения.
1public native int hashCode();
существуетhashCode()
В методе также есть некоторые условности.
- если объект использует
equals
Параметры для сравнения в методе не изменяются, то вызов объектаhashCode()
Хэш-значение, возвращаемое методом, должно быть таким же. - если два объекта проходят
equals
Метод сравнения равен,Требоватьэти два объектаhashCode
Значения, возвращаемые методами, также должны быть равны. - если два объекта проходят
equals
сравнение методов отличается, то иНе требуетэти два объектаhashCode
Значения, возвращаемые методами, не совпадают. Но мы должны знать, что генерация разных хеш-значений для разных объектов может повысить производительность для хеш-таблиц (HashMap и т. д.).
Где будет использоваться метод equals и метод hashCode
В каком классе Java часто встречаются эти два метода? Если вы виделиHashMap
Исходный код должен понимать, что эти два метода часто появляются вHashMap
середина. Онлайн-введениеHashMap
В этой категории много статей, вот краткое введениеHashMap
.
Когда связанный список в узле превышает 8, он становится красно-черным деревом, чтобы устранить недостаток медленной скорости запросов после того, как длина связанного списка станет слишком большой.
HashMap
Это эффективная структура хранения данных, состоящая из массивов и связанных списков. Так как же определить, где в массиве хранятся данные? черезhashCode
способ вычислить, где его хранить, помните, что мы сказали вышеhashCode
Метод говорит, что возможно иметь два разных объектаhashCode
Если значение, возвращаемое методом, одинаковое, то будет конфликт, а если есть конфликт, то он будет вызванequals
Методы сравниваются, если они разные, то добавляются в хвост связанного списка, если совпадают, то заменяются исходные данные.
Конечно, расчет позиции не так прост, как описано выше.
hashCode
Метод вычисляется, и в середине есть некоторые другие шаги, которые можно просто рассматривать какhashCode
Место определяется.
Когда переопределить эти два метода?
Если вы не определите свой собственный класс какHashMap
Если значение ключа , то перепишемequals
Метод без перезаписиhashCode
Метод, компилятор не сообщает об ошибках, во время выполнения не будет генерировать никаких исключений.
Если вы хотите определить свой собственный класс какHashMap
Ключ стоит, то если переписатьequals
метод также должен быть переопределенhashCode
метод.
Далее мы можем посмотреть на использование нами пользовательских классов какHashMap
ключ, и пользовательский класс не переопределяетequals
иhashCode
метод, что происходит.
пользовательский класс
1@Builder
2@NoArgsConstructor
3@AllArgsConstructor
4class CustomizedKey{
5 private Integer id;
6 private String name;
7}
Далее мы рассмотрим использование пользовательского класса в качестве ключа.
1 public static void main(String[] args) {
2
3 Map<CustomizedKey, Integer> data = getData();
4
5 CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();
6
7 Integer integer = data.get(key);
8
9 System.out.printf(String.valueOf(integer));
10 }
11
12 private static Map<CustomizedKey,Integer> getData(){
13 Map<CustomizedKey,Integer> customizedKeyIntegerMap = new HashMap<>();
14 CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();
15 customizedKeyIntegerMap.put(key,10);
16 return customizedKeyIntegerMap;
17 }
Мы видим, что последнее, что печатает программа, этоnull
ценность. Причина та же, что мы сказали выше.
-
hashCode
: Используется для расчета, где объект размещен в массиве, потому что оба являются новыми объектами, поэтому, даже если значение внутри одинаково, адрес объекта отличается, поэтому используйте по умолчаниюhashCode
разные, конечноhashMap
не будет рассматривать их как один объект.
Далее мы перепишем эти два метода. если мы используемIDEA
Если это так, просто используйте горячие клавиши напрямую.
Далее мы рассмотрим два метода, которые мы реализовали.
1@Builder
2@NoArgsConstructor
3@AllArgsConstructor
4class CustomizedKey{
5 private Integer id;
6 private String name;
7
8 @Override
9 public boolean equals(Object o) {
10 if (this == o) return true;
11 if (o == null || getClass() != o.getClass()) return false;
12 CustomizedKey that = (CustomizedKey) o;
13 return Objects.equals(id, that.id) &&
14 Objects.equals(name, that.name);
15 }
16
17 @Override
18 public int hashCode() {
19 return Objects.hash(id, name);
20 }
21}
Затем мы снова запускаем указанную выше программу и обнаруживаем, что вывод на печать стал10
.
мы также можем использовать
Lombok
который предоставил@EqualsAndHashCode
Аннотации упрощают код
Кодовый адрес этой статьи
Прошлые статьи
- Изучите эти вопросы по алгоритму связанных списков, и вы больше не будете бояться рукописных связанных списков для интервью.
- Трудно ли транзакциям Spring распространять свойства? Хватит это читать
- При разработке бэкэнд-фреймворка необходимо обратить внимание на
- Процесс оптимизации сжатого файла 20M от 30 секунд до 1 секунды
Справочная статья
- [Исходный код объекта Java]()
- Java equals() and hashCode()