Усулҳои баробар() ва hashCode() дар Java бекор карда мешаванд
Equals
ва hashCode
усулҳои бунёдии дар синф эълоншуда Object
ва дар китобхонаҳои стандартии Java мавҷудбуда мебошанд. Ин усул барои муқоисаи an objectҳо ва тавлиди рамзи бутуни an object еquals()
истифода мешавад . hashCode
Ин усулҳо дар китобхонаҳои стандартии Java ҳангоми ворид кардан ва дарёфт кардани an objectҳо ба HashMap
. Ин усул equal
инчунин барои таъмини он, ки танҳо an objectҳои беназир дар HashSet
дигар Set
амалияҳо нигоҳ дошта мешаванд, инчунин дар ҳама ҳолатҳои дигаре, ки an objectҳоро муқоиса кардан лозим аст, истифода мешавад. Татбиқи пешфарзии усул equals()
дар синф java.lang.Object
истинодҳоро бо суроғаҳои хотирае, ки тағирёбандаҳо нигоҳ медоранд ва true
танҳо дар сурати мувофиқат кардани суроғаҳо бармегардонад, ба ибораи дигар, тағирёбандаҳо ба як an object ишора мекунанд. Java тавсия медиҳад, ки усулҳо equals()
ва усулҳоро бекор кунед hashCode()
, агар шумо интизор бошед, ки муқоиса мувофиқи мантиқи табиӣ ё мантиқи тиҷорат анҷом дода шавад. Бисёр синфҳо дар китобхонаҳои стандартии Java онҳоро бекор мекунанд, масалан, синф String
баргардонида мешавад , ки агар мундариҷаи ду an objectи муқоисашаванда якхела бошанд, equals
он бармегардад . true
Синфи печанда Integer
усули equal
иҷрои муқоисаи рақамиро бекор мекунад ва ғайра. Азбаски Java HashMap
инчунин барои муқоисаи онҳо ва усулҳо такя мекунад , Java қоидаҳои зеринро барои бекор кардани ин усулҳо пешниҳод мекунад: HashTable
equals()
hashCode()
key
values
- Рефлексивӣ: Объект бояд ба худ баробар бошад.
- Симметрӣ: агар
a.equals(b)
он баргардадtrue
, он гоҳb.equals(a)
бояд баргардадtrue
. - Гузариш: агар
a.equals(b)
он баргардадtrue
ваb.equals(c)
инчунин баргардадtrue
, пасc.equals(a)
он бояд баргардадtrue
. - Пайвастагӣ: Зангҳои такрорӣ ба усул
equals()
бояд ҳамон арзишро баргардонанд, то даме ки баъзе арзишҳои моликияти an object тағир наёбанд. Яъне, агар ду an object дар Java баробар бошанд, он гоҳ онҳо то даме ки хосиятҳои онҳо бетағйир мемонанд, баробар хоҳанд буд. - Муқоиса
null
: Объект бояд барои тафтиш карда шавадnull
. Агар an object ба - баробар бошадnull
, пас усул бояд баргардадfalse
, наNullPointerException
. Масалан,a.equals(null)
он бояд баргардадfalse
.
Созишнома байни баробар ва hashCode дар Java
- Если an objectы равны по результатам выполнения метода
equals
, тогда ихhashcode
должны быть одинаковыми. - Если an objectы не равны по результатам выполнения метода
equals
, тогда ихhashcode
могут быть How одинаковыми, так и разными. Однако для повышения производительности, лучше, чтобы разные an objectы возвращали разные codeы.
Как переопределять метод equals в Java
-
@Override public boolean equals(Object obj) { /*1. Check*/
if (obj == this) { /*and return */ return true; }
-
Проверьте an object на
null
, а также проверьте, чтобы an objectы были одного типа. Не делайте проверку с помощьюinstanceof
так How такая проверка будет возвращатьtrue
для подклассов и будет работать правильно только в случае если ваш класс объявлен Howimmutable
. Вместо этого можно использоватьgetClass()
;if (obj == null || obj.getClass() != this.getClass()) { return false; }
-
Объявите переменную типа, который вы сравниваете, и приведите
obj
к этому типу. Потом сравнивайте каждый атрибут типа начиная с численных атрибутов (если имеются) потому что численные атрибуты проверяются быстрей. Сравнивайте атрибуты с помощью операторов И и ИЛИ (так называемыеshort-circuit logical operators
) для объединения проверок с другими атрибутами.Person guest = (Person) obj; return id == guest.id && (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName || (lastName != null && lastName .equals(guest.getLastName()))); }
/** * Person class with equals and hashcode implementation in Java * @author Javin Paul */
public class Person {
private int id;
private String firstName;
private String lastName;
public int getId() { return id; }
public void setId(int id) { this.id = id;}
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
Person guest = (Person) obj;
return id == guest.id
&& (firstName == guest.firstName
|| (firstName != null &&firstName.equals(guest.getFirstName()))) && (lastName == guest.lastName
|| (lastName != null && lastName .equals(guest.getLastName())
));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); result = prime * result + id; result = prime * result +
((lastName == null) ? 0 : lastName.hashCode()); return result;
}
}
Распространенные ошибки при переопределении equals в Java
-
Вместо того, чтобы переопределять метод
equals (Override)
программист перегружает его(Overload)
Синтаксис методаequals()
в классеObject
определен Howpublic boolean equals(Object obj)
, но многие программисты ненароком перегружают метод:public boolean equals(Person obj)
- instead ofObject
в качестве аргумента используют Name своего класса (напр. Person). Эту ошибку сложно обнаружить из-заstatic binding
. Таким образом, если вы вызовете этот метод для an object своего класса, то метод не просто скомпorруется, а даже сделает это корректно. Однако, если вы положите ваш an object в коллекцию, напримерArrayList
и вызовете методcontains()
, работа которого основана на методеequals()
, то методcontains
не сможет обнаружить ваш an object. -
При переопределении метода
equals()
не проверять наnull
переменные, что в конечном итоге заканчиваетсяNullPointerException
при вызовеequals()
. Ниже представлен корректный code.firstname == guest.firstname || (firstname != null && firstname.equals(guest.firstname));
-
Третья распространенная ошибка это не переопределять метод
hashCode()
, а толькоequals()
. Вы обязаны переопределять оба методаequals()
иhashCode()
в Java. МетодhashCode
используется вhash
-коллекциях(напримерHashSet
), и чем меньше будет коллизий (одинаковый code при разных an objectх) тем эффективнее эти коллекции будут работать с an objectми вашего класса. -
Последняя распространенная ошибка программистов в том, что при переопределении метода
equals()
не сохраняется соответствие между методамиequals()
иcompareTo()
, что является неформальным требованием для избежания хранения дубликатов вSet (SortedSet, TreeSet)
.
Подсказки How писать в Java метод equals
-
Аксарияти IDE-ҳо ба монанди NetBeans, Eclipse ва IntelliJ IDEA барои тавлиди усулҳо
equals()
ваhashCode()
. Дар Eclipse, тугмаи рости рост -> сарчашма ->generate equals()
ваhashCode()
. -
Агар синф калиди ягонаи тиҷорӣ дошта бошад, пас танҳо барои санҷиши баробарии ин майдонҳо кофӣ хоҳад буд. Тавре ки дар мисоли мо, "id" рақами ягона барои ҳар як Шахс аст.
-
Ҳангоми бекор кардани
hashCode()
Java, боварӣ ҳосил кунед, ки ҳамаи майдонҳоеро, ки дар метод истифода шудаанд, истифода баредequals()
. -
String
ва синфҳои печанда ба монандиInteger
,Float
ваDouble
методро бекор мекунандequals()
, аммоStringBuffer
бекор намекунад. -
То ҳадди имкон, майдонҳоро
immutable
бо истифода азfinal
тағирёбандаҳо дар Java созед. -
Ҳангоми муқоисаи
String
an objectҳоequals()
ба ҷои оператори .-ро истифода баред==
. -
Ду an objectе, ки мантиқӣ баробаранд, вале аз an objectҳои гуногун бор карда шудаанд,
ClassLoader
наметавонанд баробар бошанд. Дар хотир доред, ки тафтиш бо онgetClass()
бармегардадfalse
, агар синфи боркунак гуногун бошад. -
@Override
Эзоҳро инчунин дар усули . истифода баредhashCode
, зеро ин хатогиҳои нозукро, ба монанди арзиши баргардонидани , пешгирӣ мекунад.Боint
вуҷуди ин, баъзе барномасозон бармегардандlong
.
GO TO FULL VERSION