+1 امتیاز
قبل در برنامه نویسی توسط (1.1هزار امتیاز)

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

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

1 پاسخ

+3 امتیاز
قبل توسط (1.1هزار امتیاز)

متد های 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 شود.

سوالات مشابه

+1 امتیاز
1 پاسخ 1.2هزار بازدید
+1 امتیاز
1 پاسخ 500 بازدید
+1 امتیاز
1 پاسخ 1.2هزار بازدید
0 امتیاز
1 پاسخ 558 بازدید
سوال شده 9 سال قبل در برنامه نویسی توسط bmabma (2 امتیاز)
0 امتیاز
1 پاسخ 783 بازدید
+3 امتیاز
1 پاسخ 767 بازدید
0 امتیاز
1 پاسخ 724 بازدید
0 امتیاز
4 پاسخ 1.8هزار بازدید
سوال شده 7 سال قبل در برنامه نویسی توسط ali-nb (10 امتیاز)
...