Java-da deň () we hashCode () usullaryny ýok etmek
Equals
we hashCode
synpda yglan edilen Object
we adaty Java kitaphanalarynda bar bolan esasy usullardyr. Bu usul obýektleri deňeşdirmek we obýekt üçin bitewi kod döretmek üçin еquals()
ulanylýar . hashCode
Bu usullar, obýektleri salmak we almak üçin Java standart kitaphanalarynda giňden ulanylýar HashMap
. Bu usul, beýleki amallarda bolşy ýaly, obýektleriň deňeşdirilmeli beýleki ýagdaýlarynda-da equal
diňe täsin obýektleriň saklanmagyny üpjün etmek üçin ulanylýar . Usulyň synpda ýerine ýetirilmegi üýtgeýjileriň saklaýan we diňe salgylar gabat gelýän ýagdaýynda gaýdyp gelýän ýat salgylaryna salgylanmalary deňeşdirýär, başgaça aýdylanda üýtgeýjiler şol bir obýekte degişlidir. Java, deňeşdirmäniň tebigy logika ýa-da iş logikasyna laýyklykda edilmegine garaşsaňyz, usullary we usullary ýok etmegi maslahat berýär. Adaty Java kitaphanalarynda köp synplar olary ýok edýär, mysal üçin deňeşdirilýän iki obýektiň mazmuny birmeňzeş bolsa, synp gaýdyp gelýär . Örtük synpy san deňeşdirmesini ýerine ýetirmek usulyny ýok edýär we ş.m. Java hem deňeşdirmek üçin usullara we usullara bil baglaýandygy sebäpli , Java bu usullary ýok etmek üçin aşakdaky düzgünleri hödürleýär: HashSet
Set
equals()
java.lang.Object
true
equals()
hashCode()
String
equals
true
Integer
equal
HashMap
HashTable
equals()
hashCode()
key
values
- Reflekslilik: Obýektiň özi deň bolmaly.
- Simmetrik:
a.equals(b)
gaýdyp gelsetrue
,b.equals(a)
gaýdyp gelmelitrue
. - Geçişlik:
a.equals(b)
gaýdyp gelse -detrue
,b.equals(c)
gaýdyp gelse-true
de,c.equals(a)
gaýdyp gelmelitrue
. - Dowamlylyk: Bir usula gaýtalanýan jaňlar,
equals()
obýektiň käbir emläk bahalary üýtgemese, şol bir bahany yzyna gaýtarmaly. Javaagny, Java-da iki obýekt deň bolsa, häsiýetleri üýtgemese, deň bolar. - Deňeşdirme
null
: Obýekt barlanylmalynull
. Obýekt deň bolsanull
, usulfalse
yzyna gaýdyp gelmeliNullPointerException
. Mysal üçin,a.equals(null)
gaýdyp gelmelifalse
.
Java-da deň we hashCode arasynda ylalaşyk
- Usul ýerine ýetirilişiniň netijelerinde obýektler deň bolsa
equals
, şolhashcode
bir bolmaly. - Usul ýerine ýetirilişiniň netijelerinde obýektler deň bolmasa
equals
,hashcode
şol bir ýa-da başga bolup biler. Şeýle-de bolsa, öndürijiligi gowulandyrmak üçin dürli obýektleriň dürli kodlary yzyna gaýtarmagy has gowudyr.
Как переопределять метод 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 такие How NetBeans, Eclipse и IntelliJ IDEA обеспечивают поддержку генерации методов
equals()
иhashCode()
. В Eclipse нажмите правую кнопку -> source ->generate equals()
иhashCode()
. -
Если в классе есть уникальный бизнес-ключ, то будет достаточно сделать проверку только на equalsство этих полей. Как в нашем примере “id” - уникальный номер для каждого Person.
-
При переопределении
hashCode()
в Java удостоверьтесь в использовании всех полей, что были использованы в методеequals()
. -
String
ýaly örtük synplaryInteger
we usuly ýok etmekFloat
, ýöne ýok etmek däl.Double
equals()
StringBuffer
-
Mümkin boldugyça Java-da üýtgeýjileri
immutable
ulanyp meýdan düzüň.final
-
String
Obýektleri deňeşdireniňde ,equals()
ýerine operatory ulanyň==
. -
Logiki taýdan deň, ýöne dürli obýektlerden ýüklenen iki obýekt
ClassLoader
deň bolup bilmez. LoadadyňyzdangetClass()
çykarmaňfalse
, ýükleýji synp başga bolsa. -
@Override
Annotasiýany hem usulda ulanyňhashCode
, sebäbi bu yzyna gaýtaryş gymmaty ýaly inçe ýalňyşlyklaryň öňüni alýarint
. Someöne käbir programmistler gaýdyp gelýärlerlong
.
GO TO FULL VERSION