2011-11-23 3 views
22

शायद एक बेवकूफ सवाल है, लेकिन मैं इसे पेंच नहीं करना चाहता हूं। मान लें कि मेरे पास दो जावा कक्षाएं हैं, Class1 और Class2, जहां Class2 extends Class1 है। मैं दोनों वर्गों के लिए गुवा का उपयोग करके Object.hashcode() ओवरराइड करना चाहता हूं। सुपर क्लास के लिए, मुझे मिल गया हैएक गुवा ऑब्जेक्ट्स में सुपरक्लास को शामिल करने का सही तरीका है .शैशोड() कार्यान्वयन?

@Override 
public int hashCode() { 
    return Objects.hashcode(mField1, mField2); 
} 

Class2 के लिए, hashCode लागू करने के लिए() है कि ध्यान में Class1 के सदस्यों लेता है सही तरीके से क्या है? क्या यह इस तरह है?

@Override 
public int hashcode() { 
    return Objects.hashcode(super.hashcode(), mField3, mField4); 
} 

वह SEEMS मेरे लिए सही है, लेकिन मैं कुछ सत्यापन की तलाश में हूं। जोशुआ ब्लोच प्रभावी जावा में इस स्थिति को संबोधित नहीं करता है, और गुवा दस्तावेज़ भी नहीं हैं।

+0

पूरी तरह से उचित कार्यान्वयन, अगर Class2 के उदाहरण की समानता के साथ-साथ Class1 के क्षेत्र पर प्रतिपादित किया जाता है (। उपप्रमेय एक ही तर्क hashCode() पर लागू होता है) बग विशिष्ट होना चाहिए) super.hashCode() पर निर्भर नहीं है। –

+0

महान उत्तर और चर्चा, सभी को धन्यवाद। मेरे मामले में, मुझे कक्षा 1 और कक्षा 2 के उदाहरणों के बीच समानता का परीक्षण करने की आवश्यकता नहीं है, लेकिन नीचे दिए गए अंक जानने और समझने के लिए अच्छे हैं। –

उत्तर

13

हाँ, यह सही दिखता है। यदि आपके पास Objects.hashCode(f1, f2, f3, f4) था तो यह वही होगा। यदि आप कार्यान्वयन को देखते हैं, तो यह result += 31 * result + hashcodeOfCurrentObject जैसा कुछ है। जिसका अर्थ है कि आपका परिणाम 31 + सुपर हैशकोड होगा, जो बिल्कुल समान नहीं है, लेकिन कोई समस्या नहीं होगी। कह रही है कि आप इसे नहीं करना चाहिए द्वारा

@Override 
public int hashCode() { 
    return Objects.hashcode(mField1, getParentField1(), getParentField2()); 
} 
0

हालांकि Bozho के सुझाव मान्य है, मैं इस दृष्टिकोण पसंद करते हैं। मद 8:

ऐसा लगता है कि इस तुल्यता वस्तु उन्मुख भाषाओं में संबंधों का एक मूलभूत समस्या है। तत्काल कक्षा को विस्तारित करने का कोई तरीका नहीं है और को अनुबंध के बराबर रखते हुए एक मान घटक जोड़ें, जब तक कि आप ऑब्जेक्ट उन्मुख अमूर्तता के लाभों को छोड़ने के इच्छुक नहीं हैं।

: - यह एक गलती होगी (एक प्रदर्शन

+2

लेकिन फिर यदि पैरेंट क्लास में हैशकोड गणना बदलती है, तो उप-वर्ग का हैशकोड परिवर्तन को प्रतिबिंबित नहीं करता है। एक संभावना भी है कि सुपरक्लास हैशकोड कुछ निजी फ़ील्ड्स का उपयोग करता है जो उप-वर्ग तक पहुंच नहीं पाते हैं। – ColinD

+0

@ कोलिन्द मुझे पता है। यदि आप जानते हैं और सुपरक्लास तक पहुंच है तो यह संस्करण केवल समझ में आता है। –

+0

मुझे यकीन नहीं है कि मैं इस दृष्टिकोण का लाभ देखता हूं; क्या आप समझा सकते हैं कि आप इसे क्यों पसंद करते हैं? नकारात्मकता यह प्रतीत होती है कि अब उप-वर्ग को सुपरक्लास के क्षेत्रों का ट्रैक रखना है, जो एक परेशानी, रखरखाव के प्रकार की तरह होगा। –

10

प्रभावी जावा इस स्थिति से निपटने है ...:

+0

सं। हैशकोड() एक द्विआधारी संबंध नहीं है, इस प्रकार इसे "सममित" होने की आवश्यकता नहीं है, जो कि पदानुक्रमों के लिए समानता() तक की संपत्ति है। मुझे लगता है कि कक्षा 1 के उदाहरणों को लागू करने वाले प्रश्न में कुछ भी नहीं है, कक्षा 2 के उदाहरणों के बराबर हो सकता है, जो ई.जे. में शामिल समस्या है। –

+0

यह किसी भी तरह से सवाल से स्पष्ट नहीं है, इसलिए मैंने सोचा कि मैं कम से कम इस मामले को कवर करने का प्रयास करूंगा। –

+2

लेकिन इसे स्पष्ट करने के लिए: यदि x.equals (y), तो x.hashCode() को बराबर y.hashCode() के लिए अनुबंधित किया गया है।* यदि * हम कक्षा 1 के उदाहरणों के लिए कक्षा 2 के उदाहरणों के बराबर होना चाहते हैं, तो हमें उनके हैशकोड() कार्यान्वयन की आवश्यकता होती है, कम से कम उन मामलों में जहां विभिन्न वर्गों के उदाहरण समान हैं। –

संबंधित मुद्दे