Содержание
- 1 Если у вас есть какие-либо из перечисленных ниже проблем в Java, то вы находитесь в правильном месте.
- 2 Выход:
- 3 hashCode и equals тесно связаны:
- 4 При реализации equals поля сравниваются по-разному, в зависимости от их типа:
- 5 Реализация hashCode :
- 6 CrunchifyImplementEqualsHashCode.java
- 7 Выход Eclipse Console:
equals() а также hashCode() В Java есть два фундаментальных метода, которые объявлены в классе Object и частично или в основной библиотеке Java.
Если у вас есть какие-либо из перечисленных ниже проблем в Java, то вы находитесь в правильном месте.
- Java Practices -> Реализация равных
- переопределить — Перекрытие равно и хэш — код в Java
- Как переопределить метод equals () в Java
- Как переопределить метод hashCode () в Java
- Как переопределить метод equals и hashCode в Java
- Как и зачем переопределять метод equals в Java
- Зачем всегда переопределять hashcode (), если переопределяет equals ()?
Давайте рассмотрим простой пример, чтобы понять сначала Reference Equality а также Logical Equality , Оператор равенства (==) сравнивает ссылки (адреса в памяти) двух строк как два разных числа — это называется Reference equality ,
Logical equality сравнивает данные объектов вместо значения ссылок .
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
пакет ком . crunchify. учебные пособия ;
/ **
* @author Crunchify.com
* /
общественности учебный класс CrunchifyLogicalVsReferenceEqality {
общественности статический недействительным main ( Строка [ ] аргументы ) {
строка Стра знак равно новый String ( eBay ) ;
строка STRB знак равно новый String ( eBay ) ;
строка StRC знак равно новый String ( «Paypal» ) ;
// Создать ссылку на строку и присвоить ей ссылку на существующую строку
// чтобы обе ссылки указывали на один и тот же объект String в памяти.
строка StrD знак равно strA ;
// Распечатать результаты различных проверок на равенство
// Ссылочное равенство
Система. вне. println ( «Результат эталонного равенства:» ) ;
Система. вне. println ( strA == strB ) ;
Система. вне. println ( strA == strC ) ;
Система. вне. println ( strA == strD ) ;
// Логическое равенство
Система. вне. println ( / nLogical Equality Result: ) ;
Система. вне. println ( strA . равно ( strB ) ) ;
Система. вне. println ( strA . equals ( strC ) ) ;
Система. вне. println ( strA . equals ( strD ) ) ;
}
}
|
Выход:
|
1
2
3
4
5
6
7
8
9
|
Ссылочный результат равенства :
ложный
ложный
правда
Результат логического равенства :
правда
ложный
правда
|
hashCode и equals тесно связаны:
- если вы переопределяете equals , вы должны переопределить hashCode .
- hashCode должен генерировать равные значения для равных объектов.
- equals и hashCode должны зависеть от
same set of significant fields, Вы должны использовать один и тот же набор полей в обоих этих методах . Вы не обязаны использовать все поля. Например, вычисляемое поле, которое зависит от других, должно быть исключено изequalsа такжеhashCode,
При реализации equals поля сравниваются по-разному, в зависимости от их типа:
- поля объекта, включая коллекции : используйте равно
- типобезопасные перечисления: используйте равно или == (в данном случае они равны )
- возможно нулевые поля объекта: используйте оба == и равно
- поля массива: использовать
Arrays.equals - примитивные поля, отличные от float или double : use ==
float: преобразовать в int, используяFloat.floatToIntBits,затем используйте ==double: конвертировать в длинные, используяDouble.doubleToLongBits, затем используйте ==
Реализация hashCode :
- если класс переопределяет равно , он должен переопределить hashCode
- когда они оба переопределены, equals и hashCode должны использовать один и тот же набор полей
- если два объекта равны, то их значения hashCode также должны быть равны
- если объект неизменный , то hashCode является кандидатом на кэширование и отложенную инициализацию.
Это распространенное заблуждение, что hashCode предоставляет уникальный идентификатор для объекта. Это не.
По генеральному контракту equals() Метод в Java должен быть рефлексивным, симметричным, транзитивным, непротиворечивым , и любая ненулевая ссылка должна возвращать false. Другими словами, для произвольных значений a, b и c следующие тесты должны всегда проходить:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/ рефлексивная собственность
assertTrue ( а . равно ( а ) ) ;
// симметричное свойство
assertTrue ( а . равно ( б ) == б. равно ( а ) ) ;
// переходное свойство
если ( а . равно ( б ) && b.equals (c)) {
assertTrue (a.equals (c));
}
// свойство согласованности
assertTrue ( а . равно ( б ) == а . равно ( б ) ) ;
// ненулевое свойство
assertFalse ( а . равно ( ноль ) ) ;
|
Для лучшей практики используйте следующие шаги для реализации вашего метода equals ():
- Используйте это ==, чтобы проверить равенство ссылок
- использование
instanceofпроверить правильность типа аргумента - Приведите аргумент к правильному типу
- Сравните значимые поля на равенство
Вот полный пример.
CrunchifyImplementEqualsHashCode.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
пакет crunchify. ком . учебные пособия ;
/ **
*
* @author Crunchify.com
* Как переопределить метод equals () в Java?
* Как переопределить метод hasCode () в Java?
* версия: 1.2
*
* /
общественности учебный класс CrunchifyImplementEqualsHashCode {
общественности статический недействительным main ( Строка [ ] аргументы ) {
CrunchifyImplementEqualsHashCode crunchifyTest знак равно новый CrunchifyImplementEqualsHashCode ( ) ;
Хрустеть один знак равно новый Хруст ( 1 ) ;
Хрустеть два знак равно новый Хруст ( 1 ) ;
crunchifyTest . test1 ( один , два ) ;
Хруст три знак равно новый Хруст ( 1 ) ;
Хрустеть четыре знак равно новый Хрустить ( 2 ) ;
crunchifyTest . test2 ( три , четыре ) ;
}
общественности недействительным test1 ( Crunchify one , Хрустеть двумя ) {
если ( один . равно ( два ) ) {
Система. вне. println ( «Тест1: один и два равны» ) ;
} еще {
Система. вне. println ( «Тест1: Один и Два не равны» ) ;
}
}
общественности недействительным test2 ( Хруст три , Хрустеть четверо ) {
если ( три . равно ( четыре ) ) {
Система. вне. println ( «Test2: три и четыре равны» ) ;
} еще {
Система. вне. println ( «Test2: три и четыре не равны» ) ;
}
}
}
учебный класс Crunchify {
частный ИНТ стоимость ;
Crunchify ( int val ) {
значение знак равно val ;
}
общественности ИНТ getValue ( ) {
вернуть стоимость ;
}
// Метод переопределяет или реализует метод, объявленный в супертипе.
@Override
общественности логический равно ( объект о ) {
// нулевая проверка
если ( о == ноль ) {
вернуть ложь ;
}
// проверка этого экземпляра
если ( это == о ) {
вернуть правда ;
}
// Проверка экземпляра и проверка фактического значения
если ( ( о экземпляр Хрустеть ) && (((Crunchify) o) .getValue () == this.value)) {
вернуть истину;
} еще {
вернуть ложь ;
}
}
@Override
общественности ИНТ hashCode ( ) {
ИНТ результат знак равно 0 ;
результат знак равно ( int ) ( значение / 11 ) ;
вернуть результат ;
}
}
|
Выход Eclipse Console:
|
1
2
|
Тест1 : Один и Два из них равны
Test2 : Три и Четыре не равный
|
0.00 (0%) 0 votes







