मेरी कक्षाओं के लिए कैसे काम करेगा?


106

कहो कि मेरी अपनी कक्षा है

public class MyObj { /* ... */ }

इसकी कुछ विशेषताएँ और विधियाँ हैं। यह समान लागू नहीं करता है, हैशकोड लागू नहीं करता है।

एक बार जब हम बराबर और हैशकोड कहते हैं, तो डिफ़ॉल्ट कार्यान्वयन क्या हैं? ऑब्जेक्ट क्लास से? और वे क्या हैं? डिफ़ॉल्ट समान कैसे काम करेगा? डिफ़ॉल्ट हैशकोड कैसे काम करेगा और क्या लौटेगा? == सिर्फ जाँच करेगा कि क्या वे एक ही वस्तु के संदर्भ में हैं, इसलिए यह आसान है, लेकिन बराबरी () और हैशकोड () विधियों के बारे में क्या?

जवाबों:


94

हां, डिफ़ॉल्ट कार्यान्वयन ऑब्जेक्ट (आमतौर पर बोल रहा है; यदि आप एक वर्ग से विरासत में मिला है जो समान और / या हैशकोड को फिर से परिभाषित करता है, तो आप उस कार्यान्वयन का उपयोग करेंगे)।

प्रलेखन से:

equals

क्लास ऑब्जेक्ट के लिए समान पद्धति वस्तुओं पर सबसे अधिक भेदभावपूर्ण संभावित समानता संबंध को लागू करती है; यह है कि किसी भी गैर-शून्य संदर्भ मानों के लिए x और y, यह विधि सही है और यदि केवल x और y एक ही ऑब्जेक्ट को संदर्भित करते हैं (x == y का मान सत्य है)।

hashCode

जितना अधिक व्यावहारिक रूप से व्यावहारिक है, क्लास ऑब्जेक्ट द्वारा परिभाषित हैशकोड विधि अलग-अलग वस्तुओं के लिए अलग-अलग पूर्णांक लौटाती है। (यह आमतौर पर ऑब्जेक्ट के आंतरिक पते को पूर्णांक में परिवर्तित करके कार्यान्वित किया जाता है, लेकिन यह कार्यान्वयन तकनीक JavaTM प्रोग्रामिंग भाषा द्वारा आवश्यक नहीं है।)


50

से ObjectJVM कार्यान्वयन में से एक में:

public boolean equals(Object object) {
    return this == object;
}

public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}

दोनों मामलों में यह प्रश्न में वस्तुओं के मेमोरी पतों की तुलना कर रहा है।


7
JDK के किस संस्करण से? में v6u23 ea:public native int hashCode();

@ रेखा - आप सही कह रहे हैं, मुझे लगता है कि मैंने वास्तव में जो किया है, उसे देखने के लिए मैंने मूल कार्यान्वयन में से एक को ट्रैक किया
ब्रैड मेस

10

वहाँ के डिफ़ॉल्ट कार्यान्वयन हैं equals()और hashCode()वस्तु में। यदि आप अपना स्वयं का कार्यान्वयन प्रदान नहीं करते हैं, तो उनका उपयोग किया जाएगा। इसके लिए equals(), इसका मतलब एक ==तुलना है: ऑब्जेक्ट केवल समान होंगे यदि वे वास्तव में एक ही वस्तु हैं। के लिए hashCode(), Javadoc की एक अच्छी व्याख्या है।

अधिक जानकारी के लिए, प्रभावी जावा, अध्याय 3 (पीडीएफ), आइटम 8 देखें।


1

हाँ, Objectजब से आपकी कक्षा फैली हुई है , तब से कक्षा से। equalsबस लौटता है this == objhashCodeकार्यान्वयन मूल है। बस एक अनुमान है - यह संकेतक को वस्तु में वापस करता है।


2
यह मेमोरी में स्थित ऑब्जेक्ट का पॉइंटर है, लेकिन यह ऑब्जेक्ट का मेमोरी एड्रेस नहीं है। जीसी मेमोरी में ऑब्जेक्ट को चारों ओर ले जा सकता है और हैश कोड समान रहेगा।
जेरेमी

@ जेरेमी धन्यवाद। stackoverflow.com/questions/2427631/… दिलचस्प हो सकता है।
18

1

यदि आप अपना स्वयं का कार्यान्वयन प्रदान नहीं करते हैं, तो ऑब्जेक्ट से प्राप्त एक का उपयोग किया जाएगा। यह ठीक है, जब तक कि आप अपने वर्ग के उदाहरणों को हैशसेट (किसी भी संग्रह में जो वास्तव में हैशकोड ()) का उपयोग करते हैं, या ऐसा कुछ नहीं है, जो वस्तु की समानता (यानी हैशसेट समाहित है) (विधि) की जांच करने की आवश्यकता है। अन्यथा यह गलत तरीके से काम करेगा, अगर आप यही पूछ रहे हैं।

HashCodeBuilder और Apals Commun Lang से EqualsBuilder के लिए धन्यवाद, इन विधियों का अपना स्वयं का कार्यान्वयन प्रदान करना काफी आसान है ।


(क) आप क्यों कहते हैं कि ऑब्जेक्ट क्लास का 'डिफॉल्ट इम्प्लीमेंट' 'हैशसेट के साथ सही तरीके से काम नहीं करेगा? यह इस पृष्ठ पर अन्य उत्तरों का खंडन करता है। (b) कॉमन्स लैंग लिंक के लिए धन्यवाद।
बेसिल बॉर्क

1
@ बासील: मुझे नहीं लगता कि विरोधाभासी। निश्चित रूप से डिफ़ॉल्ट कार्यान्वयन काम करेगा ... किसी भी तरह, लेकिन जिस तरह से आप अपेक्षा करते हैं। यही है, क्योंकि समतुल्य () संदर्भ समानता का उपयोग करता है, दो अन्यथा समान वस्तुएं डिफ़ॉल्ट कार्यान्वयन की दृष्टि में "अलग" होंगी। परिणामस्वरूप, आप अपने सेट में वास्तव में एक ही चीज़ के दो अलग-अलग उदाहरण हो सकते हैं। और जब आप डुप्लिकेट को खत्म करना चाहते हैं तो सेट्स का विशिष्ट उपयोग होता है ...
पावेल डिडा

@ PawełDyda: डिफ़ॉल्ट व्यवहार आम तौर पर उत्परिवर्तनीय प्रकारों के लिए सही है। यदि Fooऔर Barएक उत्परिवर्तित प्रकार के दो अलग-अलग उदाहरणों के संदर्भ हैं, और एक विधि मौजूद है (जैसे SomeMutatingMethod) जैसे कि Foo.SomeMutatingMethod()यह Barउसी तरह से प्रभावित नहीं करता है Foo, तो यह अंतर वस्तुओं को असमान के रूप में मानने के लिए पर्याप्त होना चाहिए।
सुपरैट

0

आईबीएम के विकासकर्ता कहते हैं:

इस डिफ़ॉल्ट कार्यान्वयन के तहत, दो संदर्भ समान हैं यदि वे सटीक समान ऑब्जेक्ट को संदर्भित करते हैं। इसी प्रकार, ऑब्जेक्ट द्वारा प्रदान किए गए हैशकोड () का डिफ़ॉल्ट कार्यान्वयन ऑब्जेक्ट के मेमोरी एड्रेस को एक पूर्णांक मान पर मैप करके निकाला जाता है।

हालांकि, किसी विशेष विक्रेता के जावा संस्करण के लिए सटीक कार्यान्वयन विवरणों के बारे में सुनिश्चित होना यह स्रोत के रूप में देखने के लिए संभवतः सबसे अच्छा है (यदि यह उपलब्ध है)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.