کاربرد متد های equals و hashCode در جاوا چیست؟

+1 رأی
میانگین بازدید روزانه 1.472,594 بازدید

کاربرد متد های equals و hashCode در جاوا چیست و اینکه آیا باید در زمان تعریف کلاس های جدید آنها را override کنیم؟

سوال 4 سال قبل در تالار برنامه نویسی توسط Saeed Zarinfam (727 امتیاز)
چرا با وجود اینکه متد hashcode  در کلاس object هست ولی برای بررسی کردن اینکه دو شی در hashset مساوی هستند باید hashcode  را override  کرد؟
آیا برای تمام collection  ها باید متد hashCode را override  کنیم؟

1 جواب

+3 رأی

متد های equals و hashCode در کلاس Object که بصورت پیشفرض پدر تمام کلاس ها در زبان برنامه نویسی جاوا است قرار دارند. کاربرد اصلی این دو متد برای تعریف برابری (equality) اشیاء ساخته شده از یک کلاس است و با override کردن آنها شما می توانید تعریف پیشفرض برابری (equality) اشیاء در جاوا را برای کلاس مورد نظر خود بازنویسی کنید.

متد equals برای مقایسه برابری دو شئ استفاده می شود و اگر دو شئ بر اساس متد equals کلاسشان، برابر باشند حتما باید خروجی متد hashCode آنها نیز برابر باشد ولی لزوما دو شئ که خروجی متد hashCode آنها برابر است با هم برابر نیستند!

collection ها در جاوا برای مقایسه عناصر از متد equals استفاده می کنند.

متد equals به تنهایی برای مقایسه برابری دو شئ کفایت می کند. چون متد equals بصورت پیشفرض reference های دو شئ در حافظه JVM را مقایسه می کند (همانند عملگر == برای انواع داده ارجاعی) برای اینکه مقایسه بر مبنای مقادیر درون شئ باشد حتما باید متد equals کلاس را override کرد:

public class Employee {
  protected long   employeeId;
  protected String firstName;
  protected String lastName;

  public boolean equals(Object o){
    if(o == null)                return false;
    if(!(o instanceof) Employee) return false;

    Employee other = (Employee) o;
    return this.employeeId == other.employeeId;
  }
}

در پیاده سازی جدید متد equals برای کلاس Employee، معیار برابر بودن برابر بودن فیلد employeeId در نظر گرفته شده است.

وقتی یک شئ را به hash-based collection ها مثل HashTable, HashMap یا HashSet اضافه می کنیم، این collection ها با استفاده از متد hashCode ، کلید hash مورد نیاز خود را بدست می آورند و از آن کلید برای ذخیره سازی و جستجو استفاده می کنند. 

hash-based collection ها از hashCode فقط برای پیدا کردن محلی که شئ ذخیره شده است استفاده می کنند، چون ممکن است چند شئ متفاوت hashCode یکسان داشته باشند پس از پیدا کردن آنها از متد equals برای مقایسه بین آنها استفاده می شود. برای مثال Employee پیاده سازی متد equals بصورت زیر کفایت می کند:

public class Employee {
  protected long   employeeId;
  protected String firstName;
  protected String lastName;

  public int hashCode(){
    return (int) employeeId;
  }
}

درست است که بسیاری از کارمندان بدلیل cast شدن employeeId آنها از long به int، مقدار hashCode یکسان خواهند داشت ولی این کارمندان با توجه به پیاده سازی جدید متد equals برابر نخواهند بود و مشکلی برای hash-based collection ها بوجود نخواهد آمد.

پیاده سازی پیشفرض متد hashCode برای تولید hashCode هر شئ به مقادیر درون شئ توجهی نمی کند و بر اساس reference حافظه آن شئ hashCode تولید می کند و بدلیل اینکه در hash-based collection ها وقتی دو شئ برابر هستند حتما باید hashCode آنها نیز برابر باشد توصیه می شود وقتی متد equals یک کلاس override می شود متد hashCode آن نیز override شود.

جواب 4 سال قبل توسط Saeed Zarinfam (727 امتیاز)

سوال های مشابه

+1 رأی
1 جواب میانگین بازدید روزانه 0.61612 بازدید
+3 رأی
1 جواب میانگین بازدید روزانه 0.15397 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.13207 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.41723 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.2350 بازدید
سوال 4 سال قبل در تالار برنامه نویسی توسط bmabma (2 امتیاز)
0 رأی
1 جواب میانگین بازدید روزانه 0.15381 بازدید
+3 رأی
1 جواب میانگین بازدید روزانه 0.15352 بازدید
+1 رأی
1 جواب میانگین بازدید روزانه 0.19367 بازدید
0 رأی
1 جواب میانگین بازدید روزانه 0.15175 بازدید
0 رأی
4 جواب میانگین بازدید روزانه 0.47634 بازدید
سوال 3 سال قبل در تالار برنامه نویسی توسط ali-nb (10 امتیاز)
کانال تلگرام جواب یاب
...