पाठ 25 / 38
equals() व hashCode()
equals() और hashCode() को सही व एक साथ ओवरराइड करें ताकि आपके ऑब्जेक्ट HashMap, HashSet और हर जगह जहाँ समानता मायने रखती है, सही व्यवहार करें।
डिफ़ॉल्ट पहचान है
Object का डिफ़ॉल्ट equals() बस == (रेफ़रेंस पहचान) है, और डिफ़ॉल्ट hashCode() उसी पहचान से निकलता है। अगर दो ऑब्जेक्ट सामग्री से "बराबर" होने चाहिए (जैसे दो Point(1,2)), तो दोनों मेथड खुद ओवरराइड करने होंगे।
कॉन्ट्रैक्ट
स्वर्णिम नियम: अगर a.equals(b) true है, तो a.hashCode() == b.hashCode() भी true होना चाहिए। इसे तोड़ने पर ऑब्जेक्ट HashMap/HashSet लुकअप में चुपचाप गायब हो जाते हैं। दोनों मेथड में एक जैसी फ़ील्ड उपयोग करें।
public final class Point {
private final int x, y;
// ... constructor, getters ...
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override public int hashCode() {
return Objects.hash(x, y);
}
}त्वरित जाँच
त्वरित जाँच: आप equals() ओवरराइड करते हैं पर hashCode() भूल जाते हैं। क्या टूटता है?
- कुछ नहीं, दोनों स्वतंत्र हैं
- कम्पाइलेशन विफल होता है
- "बराबर" ऑब्जेक्ट अलग HashMap बकेट में पहुँच सकते हैं और लुकअप विफल हो सकता है
- equals() खुद रनटाइम पर त्रुटि देता है
Answer
"बराबर" ऑब्जेक्ट अलग HashMap बकेट में पहुँच सकते हैं और लुकअप विफल हो सकता है — हैश-आधारित कलेक्शन पहले hashCode() से बकेट चुनते हैं, फिर उसमें equals() जाँचते हैं। बेमेल hashCode() से बराबर ऑब्जेक्ट गलत बकेट में खोजे जा सकते हैं और कभी नहीं मिलते।