جاوا میں برابر () اور ہیش کوڈ () طریقوں کو اوور رائیڈ کرنا
Equals
اور hashCode
کلاس میں اعلان کردہ Object
اور معیاری جاوا لائبریریوں میں موجود بنیادی طریقے ہیں۔ یہ طریقہ еquals()
اشیاء کا موازنہ کرنے اور hashCode
آبجیکٹ کے لیے ایک عدد کوڈ بنانے کے لیے استعمال کیا جاتا ہے۔ یہ طریقے جاوا معیاری لائبریریوں میں بڑے پیمانے پر استعمال ہوتے ہیں جب میں اشیاء کو داخل اور بازیافت کرتے ہیں HashMap
۔ اس طریقہ کار کا equal
استعمال اس بات کو یقینی بنانے کے لیے بھی کیا جاتا ہے کہ صرف منفرد اشیاء کو HashSet
دیگر Set
نفاذات میں ذخیرہ کیا جاتا ہے، اور ساتھ ہی کسی بھی دوسری صورت میں جہاں اشیاء کا موازنہ کرنے کی ضرورت ہوتی ہے۔ equals()
کلاس میں طریقہ کار کا پہلے سے طے شدہ نفاذ java.lang.Object
ان میموری ایڈریسز سے حوالہ جات کا موازنہ کرتا ہے جو متغیرات اسٹور کرتے ہیں اور true
صرف اس صورت میں واپس آتے ہیں جب ایڈریسز آپس میں مماثل ہوں، دوسرے لفظوں میں، متغیرات ایک ہی چیز کا حوالہ دیتے ہیں۔ اگر آپ توقع کرتے ہیں کہ موازنہ قدرتی منطق یا کاروباری منطق کے مطابق کیا جائے تو جاوا equals()
اور طریقوں کو اوور رائیڈ کرنے کی تجویز کرتا ہے۔ hashCode()
معیاری جاوا لائبریریوں میں بہت سی کلاسیں ان کو اوور رائیڈ کرتی ہیں، مثال کے طور پر کلاس کو String
اوور رائیڈ کرتا ہے equals
تاکہ یہ واپس آجائے true
اگر ان دونوں اشیاء کے مواد کا موازنہ کیا جا رہا ہے۔ ریپر کلاس عددی موازنہ کرنے کے Integer
طریقہ کو اوور رائیڈ کرتی ہے equal
، وغیرہ۔ چونکہ جاوا ان کے اور کا موازنہ کرنے کے طریقوں پر HashMap
بھی انحصار کرتا ہے ، جاوا ان طریقوں کو اوور رائیڈ کرنے کے لیے درج ذیل اصول پیش کرتا ہے۔ HashTable
equals()
hashCode()
key
values
- اضطراری صلاحیت: آبجیکٹ کو اپنے برابر ہونا چاہیے۔
- سڈول: اگر
a.equals(b)
یہ لوٹتا ہےtrue
، توb.equals(a)
اسے بھی لوٹنا چاہیےtrue
۔ - Transitivity: اگر
a.equals(b)
یہ لوٹتا ہےtrue
اورb.equals(c)
واپس بھی آتا ہےtrue
، توc.equals(a)
اسے بھی واپس آنا چاہیےtrue
۔ - مستقل مزاجی: کسی طریقہ پر بار بار کی جانے والی کالوں کو
equals()
ایک ہی قدر واپس کرنی چاہیے جب تک کہ آبجیکٹ کی کچھ خاصیت کی قدروں کو تبدیل نہ کیا جائے۔ یعنی، اگر جاوا میں دو اشیاء برابر ہیں، تو وہ اس وقت تک برابر رہیں گی جب تک کہ ان کی خصوصیات میں کوئی تبدیلی نہ ہو۔ - موازنہ
null
: آبجیکٹ کو چیک کرنا ضروری ہےnull
۔ اگر اعتراض کے برابر ہےnull
، تو طریقہ واپس آنا چاہیےfalse
، نہیںNullPointerException
۔ مثال کے طور پر،a.equals(null)
اسے واپس آنا چاہیےfalse
۔
جاوا میں مساوی اور ہیش کوڈ کے درمیان معاہدہ
- اگر آبجیکٹ طریقہ کار پر عمل درآمد کے نتائج میں برابر ہیں
equals
، تو انہیںhashcode
ایک جیسا ہونا چاہیے۔ - اگر طریقہ کار کے نتائج میں اشیاء برابر نہیں ہیں
equals
، تو وہhashcode
یا تو ایک جیسے یا مختلف ہو سکتے ہیں۔ تاہم، کارکردگی کو بہتر بنانے کے لیے، یہ بہتر ہے کہ مختلف اشیاء مختلف کوڈز واپس کریں۔
جاوا میں مساوی طریقہ کو کیسے اوور رائڈ کریں۔
-
@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
اور ریپر کلاسز جیسے کہInteger
,Float
اورDouble
طریقہ کو اوور رائیڈ کرتا ہےequals()
لیکنStringBuffer
اوور رائڈ نہیں کرتا۔ -
جب بھی ممکن ہو، جاوا میں متغیرات کا
immutable
استعمال کرتے ہوئے فیلڈز بنائیں ۔final
-
اشیاء کا موازنہ کرتے وقت
String
،equals()
اس کے بجائے . operator استعمال کریں==
۔ -
دو اشیاء جو منطقی طور پر برابر ہیں لیکن مختلف اشیاء سے بھری ہوئی ہیں
ClassLoader
برابر نہیں ہو سکتیں۔ یاد رکھیں کہ اگر لوڈر کلاس مختلف ہے تو اس کے ساتھ چیکنگgetClass()
واپس آ جائے گی ۔false
-
@Override
تشریح کو . طریقہ پر بھی استعمال کریںhashCode
، کیونکہ یہ ٹھیک ٹھیک غلطیوں کو روکتا ہے جیسے کی واپسی کی قدرint
، تاہم، کچھ پروگرامرز واپس آتے ہیںlong
۔
GO TO FULL VERSION