Java-da equals() və hashCode() metodlarını ləğv etmək
Equals
və hashCode
sinifdə elan edilmiş Object
və standart Java kitabxanalarında olan fundamental metodlardır. Metod obyektləri müqayisə etmək və obyekt üçün tam kod yaratmaq üçün еquals()
istifadə olunur . hashCode
Bu üsullar Java standart kitabxanalarında obyektlərin daxil edilməsi və götürülməsi zamanı geniş istifadə olunur HashMap
. Metod həmçinin digər tətbiqlərdə, eləcə də obyektlərin müqayisə edilməli olduğu hər hansı digər hallarda equal
yalnız unikal obyektlərin saxlanmasını təmin etmək üçün istifadə olunur . Sinifdə metodun standart tətbiqi dəyişənlərin saxladığı yaddaş ünvanlarına istinadları müqayisə edir və yalnız ünvanlar uyğunlaşdıqda qaytarır, başqa sözlə, dəyişənlər eyni obyektə istinad edir. Əgər müqayisənin təbii məntiqə və ya biznes məntiqinə uyğun aparılacağını gözləyirsinizsə, Java və metodlarını ləğv etməyi tövsiyə edir. Standart Java kitabxanalarındakı bir çox siniflər onları ləğv edir, məsələn, müqayisə olunan iki obyektin məzmunu eyni olduqda, sinif geri qaytarılması üçün onları ləğv edir . Sarmalayıcı sinfi ədədi müqayisəni yerinə yetirmək üçün metodu ləğv edir və s. Java həm də onların və -lərini müqayisə etmək üçün metodlara və metodlara etibar etdiyi üçün Java bu metodları ləğv etmək üçün aşağıdakı qaydaları təklif edir: HashSet
Set
equals()
java.lang.Object
true
equals()
hashCode()
String
equals
true
Integer
equal
HashMap
HashTable
equals()
hashCode()
key
values
- Refleksivlik: Obyekt özünə bərabər olmalıdır.
- Simmetrik: qaytarırsa
a.equals(b)
,true
ob.equals(a)
da qayıtmalıdırtrue
. - Transitivlik:
a.equals(b)
qayıdırsatrue
vəb.equals(c)
həmçinin qayıdırsatrue
,c.equals(a)
o da qayıtmalıdırtrue
. - Ardıcıllıq: Bir metoda təkrar edilən zənglər
equals()
obyektin bəzi xüsusiyyət dəyərlərinin dəyişdirilmədiyi müddətcə eyni dəyəri qaytarmalıdır. Yəni Java-da iki obyekt bərabərdirsə, o zaman xassələri dəyişməz qaldıqca onlar bərabər olacaqlar. - Müqayisə
null
: Obyekt yoxlanılmalıdırnull
. Əgər obyekt bərabərdirsə , o zaman metod deyil,null
qayıtmalıdır . Məsələn, qayıtmalıdır .false
NullPointerException
a.equals(null)
false
Java-da bərabər və hashCode arasında razılaşma
- Если 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
-
NetBeans, Eclipse və IntelliJ IDEA kimi əksər IDE-lər metodların yaradılması
equals()
vəhashCode()
. Eclipse-də sağ klikləyin -> mənbə ->generate equals()
vəhashCode()
. -
Sinfin unikal biznes açarı varsa, o zaman yalnız bu sahələrin bərabərliyini yoxlamaq kifayətdir. Nümunəmizdə olduğu kimi, “id” hər bir şəxs üçün unikal nömrədir.
-
Java-da ləğv edərkən
hashCode()
, metodda istifadə olunan bütün sahələrdən istifadə etdiyinizə əmin olunequals()
. -
String
və kimi sarğı sinifləriInteger
və metodu ləğv edirFloat
, lakin ləğv etmir.Double
equals()
StringBuffer
-
Mümkünsə, Java-da dəyişənlərdən
immutable
istifadə edərək sahələr yaradınfinal
. -
String
Obyektləri müqayisə edərkənequals()
yerinə . operatorundan istifadə edin==
. -
Məntiqi cəhətdən bərabər olan, lakin fərqli obyektlərdən yüklənən iki obyekt
ClassLoader
bərabər ola bilməz. Unutmayın ki , yükləyici sinfi fərqli olarsa, ilə yoxlamagetClass()
geri qayıdacaq .false
-
@Override
Annotasiyadan .metodunda da istifadə edinhashCode
, çünki bu , məsələn , geri qaytarma dəyəri kimi incə xətaların qarşısını alır.Lakinint
bəzi proqramçılar geri qayıdırlarlong
.
GO TO FULL VERSION