2012-10-30 33 views
12

संभव डुप्लिकेट:
Overriding equals and hashCode in Javaमुझे बराबर और हैशकोड विधियों को ओवरराइड करने की आवश्यकता कब होगी?

अगर मैं

class A { 
    int x = 1; 
} 
... 
A a1 = new A(); 
A a2 = new A(); 
a1.equals(a2); 

है, तो मैं बराबर विधि ओवरराइड के बिना एक के 2 उदाहरणों की तुलना, मैं परिणाम की उम्मीद हो जाएगा?

+0

इस से संबंधित है के लिए कार्रवाई करने के लिए नहीं, बल्कि http का डुप्लिकेट: // stackoverflow .com/प्रश्न/27581/ओवरराइडिंग-बराबर-और-हैशकोड-इन-जावा क्योंकि यह * बराबर * और 'हैकोड 'को ओवरराइड करने के बारे में है, जबकि यह ओवरराइड करने के बारे में * कब * है। – Raedwald

+0

यह एक बेहतर डुप्लिकेट प्रतीत होता है: http://stackoverflow.com/questions/13387742 –

उत्तर

28

यदि मैं बराबर विधि को ओवरराइड किए बिना ए के 2 उदाहरणों की तुलना करता हूं, तो मुझे अपेक्षित परिणाम मिलेगा?

कि आप क्या उम्मीद :) पर निर्भर करता है

डिफ़ॉल्ट कार्यान्वयन आप संदर्भ समानता दे देंगे - दूसरे शब्दों में, जब आप दो संदर्भों तुलना, equals ही सच्चा वापस आ जाएगी अगर वे कर रहे हैं के लिए संदर्भ एक ही वस्तु

आप आमतौर पर "मूल्य समानता" को लागू करने के लिए equals ओवरराइड करेंगे - जहां दो अलग-अलग वस्तुओं को बराबर समझा जाता है, आमतौर पर बराबर फ़ील्ड मानों के आधार पर। समानता का सटीक अर्थ आपके डिजाइन पर निर्भर करेगा - उदाहरण के लिए, दो वस्तुएं अभी भी अन्य तरीकों से अलग-अलग हो सकती हैं।

आप equals ओवरराइड हैं, तो आप भी ओवरराइड hashCode संगत equals साथ रहना चाहिए, इस तरह है कि अगर a.equals(b) सत्य है, तभी a.hashCode() == b.hashCode()। यह हैश-आधारित संग्रहों (जैसे HashMap) में कुंजियों के रूप में उपयोग करने के लिए आपकी कक्षा के उदाहरणों को अनुमति देगा ताकि आप किसी संदर्भ का उपयोग करने के बजाए बराबर मूल पर एक मान के आधार पर एक मूल्य देख सकें। सटीक मूल कुंजी वस्तु के लिए।

+8

तो इसका मतलब यह है कि, यदि मैं समान विधि को ओवरराइड नहीं करता हूं, तो बराबर() समान == के रूप में कार्य करता है? – user926958

+8

@ user926958: हाँ, बिल्कुल। –

2

equals का डिफ़ॉल्ट कार्यान्वयन परीक्षण करता है कि चर एक ही वस्तु का संदर्भ देते हैं या नहीं। यदि वह नहीं है जो आप चाहते हैं, तो आपको equals ओवरराइड करने की आवश्यकता है। जब आप equals को ओवरराइड करते हैं तो आपको आमतौर पर हैश टेबल (या हैश कोड का उपयोग करने वाले अन्य डेटा संरचनाओं) में उपयोग करने योग्य ऑब्जेक्ट के लिए hashcode ओवरराइड करने की आवश्यकता होती है।

3

यदि मैं बराबर विधि को ओवरराइड किए बिना ए के 2 उदाहरणों की तुलना करता हूं, तो मुझे अपेक्षित परिणाम मिलेगा?

नहीं। चूंकि आपने दो अलग-अलग उदाहरण स्पष्ट रूप से बनाए हैं।

क्यों? के डिफ़ॉल्ट कार्यान्वयन के बराबर होती है चेकों दो चिंतित वस्तुओं जावा आभासी स्मृति में एक ही स्मृति स्थान को इंगित कि क्या

(और इस डिफ़ॉल्ट व्यवहार java.lang.Object.equals() में परिभाषित किया गया है) जब मैं की जरूरत है बराबर और हैशकोड विधियों को ओवरराइड करने के लिए?

सबसे आम स्थिति में जब प्रोग्रामर दोनों बराबर ओवरराइड() और hashCode() आप java.util.Map कार्यान्वयन में के रूप में

  1. कुंजी चिंतित वर्ग के उदाहरण उपयोग करने की आवश्यकता है, तो कर रहे हैं
  2. Java.util.Set कार्यान्वयन में मान
  3. आप उसी वर्ग के दो अलग-अलग उदाहरणों के बीच मूल्यों की समानता की जांच करना चाहते हैं (इस मामले में ओवरराइडिंग बराबर() अनिवार्य है, हैशकोड() नहीं है - लेकिन यह एक अच्छा प्रोग्रामिंग अभ्यास है)

बराबरी और hashCode के जनरल अनुबंध है:

if a1.equals(a2) 
    it is mandatory that a1.hashcode() == a2.hashcode() 
if a1.hashcode() == a2.hashcode() 
    it is not mandatory that a1.equals(a2) 

मुझे लगता है कि पर्याप्त डेटा एक दिन :)