Домой Учебники по Java и J2EE Коллекции Java — hashCode () и equals () — Как переопределить метод...

Коллекции Java — hashCode () и equals () — Как переопределить метод equals () и hashcode () в Java?

941
0

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 сравнивает данные объектов вместо значения ссылок .

CrunchifyLogicalVsReferenceEqality.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
пакет ком . 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 , затем используйте ==
ЧИТАТЬ ТАКЖЕ:  В Java Как найти средний элемент LinkedList?

Реализация 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

CrunchifyImplementEquals.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 : Три и Четыре не равный
Коллекции Java — hashCode () и equals () — Как переопределить метод equals () и hashcode () в Java?

0.00 (0%) 0 votes

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь