2010-06-06 14 views
10

मैं जावा में ऑब्जेक्ट समानता के आसपास कुछ कोड कोशिश कर रहा हूं। जैसा कि मैंने कहीं पढ़ा हैक्यों हैशकोड() लगातार सभी निष्पादन में ऑब्जेक्ट के लिए समान मान देता है?

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

अब, मेरे पास नमूना प्रोग्राम है, जो मैं लगातार 10 बार चलाता हूं। हर बार जब मैं प्रोग्राम चलाता हूं तो मुझे हैश कोड के समान मूल्य मिलता है।

यदि hashCode() फ़ंक्शन ऑब्जेक्ट के लिए स्मृति स्थान देता है, तो जावा (JVM) ऑब्जेक्ट को लगातार रन में उसी स्मृति पते पर कैसे संग्रहीत करता है?

क्या आप कृपया मुझे इस मुद्दे पर कुछ अंतर्दृष्टि और अपना विचार दे सकते हैं?

कार्यक्रम मैं इस व्यवहार को परीक्षण करने के लिए चला रहा हूँ नीचे है:

public class EqualityIndex { 

    private int index; 

    public EqualityIndex(int initialIndex) { 
     this.index = initialIndex; 
    } 

    public static void main(String[] args) { 
     EqualityIndex ei = new EqualityIndex(2); 
     System.out.println(ei.hashCode()); 
    } 

} 

हर बार जब मैं इस कार्यक्रम हैश कोड दिए गए मान 4072869 है चलाते हैं।

+0

आपकी ऑब्जेक्ट्स क्या हैं? कुछ कोड दिखाएं – Bozho

+0

क्या आप वाकई अपना मान स्मृति पता है? क्या आप इसे पोस्ट कर सकते हैं? – vodkhang

+1

जावा का डिफ़ॉल्ट '.शैशकोड() 'वास्तव में * एड्रेस * की तुलना में एक वृद्धिशील स्मृति * पहचानकर्ता * की तरह अधिक है, इसलिए स्वाभाविक रूप से जब पूर्व शर्त समान होती है, तो परिणाम भी होता है। – Esko

उत्तर

14

जावा (JVM) ऑब्जेक्ट को लगातार रन में उसी स्मृति पते पर कैसे संग्रहीत करता है?

ऐसा क्यों नहीं होगा? गैर कर्नेल प्रोग्राम पूर्ण स्मृति पते के साथ कभी काम नहीं करते हैं, वे वर्चुअल मेमोरी का उपयोग करते हैं जहां प्रत्येक प्रक्रिया को अपना पता स्थान मिलता है। इसलिए यह कोई आश्चर्य की बात नहीं है कि एक निर्धारिती कार्यक्रम प्रत्येक रन में एक ही स्थान पर सामान रखेगा।

+0

यह ध्यान देने योग्य है कि यह उत्तर आधुनिक JVMs पर लागू नहीं होता है। उदाहरण के लिए, डिफ़ॉल्ट रूप से जेडीके 7 के 'ऑब्जेक्ट.hashCode()' ऑब्जेक्ट के पते ** का उपयोग नहीं करता ** **। Http://stackoverflow.com/questions/13860194/what-is-an-internal-address-in-java/13860488#13860488 – NPE

2

आपको किस प्रकार की वस्तु बनाई गई है? क्या यह एक विशिष्ट प्रकार की वस्तु है जैसे स्ट्रिंग (उदा।)। यदि यह एक विशिष्ट प्रकार है, तो वर्ग पहले से ही हैशकोड() विधि को ओवरराइड कर सकता है और इसे आपके पास वापस कर सकता है। उस स्थिति में, आपको जो भी मिलता है वह स्मृति पता नहीं है।

और आपको जो मूल्य मिलते हैं, क्या आप निश्चित हैं कि यह स्मृति पता है या नहीं?

तो, अधिक जानकारी के

3

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

1

हैशकोड आपके द्वारा उपयोग की जाने वाली कक्षा द्वारा the JavaDoc for Object.hashCode() कहलाता है और इसे ओवरराइड किया जा सकता है, यह कहता है कि यह '... वस्तु के आंतरिक पते को एक पूर्णांक में परिवर्तित करके लागू किया जाता है ...' इसलिए वास्तविक कार्यान्वयन प्रणाली हो सकती है निर्भर। JavaDoc में तीसरा बिंदु भी नोट करें कि दो ऑब्जेक्ट्स जो बराबर नहीं हैं, उन्हें विभिन्न हैशकोड वापस करने की आवश्यकता नहीं है।

0

यदि दो वस्तुएं बराबर हैं, तो उनके पास समान हैश कोड होना चाहिए। इसलिए, जब तक आप सादा Object उदाहरण नहीं बनाते, हर बार जब आप ऑब्जेक्ट बनाते हैं जिसमें एक ही मान होता है, तो आपको एक ही हैश कोड मिल जाएगा।

+0

देखें यह हमेशा सत्य नहीं है। यह उस वर्ग पर निर्भर करता है जिसके बारे में आप बात कर रहे हैं। यह बराबर और हैशकोड को हमेशा ओवरराइड करने के लिए एक अच्छा सम्मेलन है लेकिन यह हमेशा सत्य नहीं है – vodkhang

+0

बेशक, यदि वस्तु तुलनीय हैं। –

+0

जब आप कहते हैं कि "होना है", तो आप वास्तव में "होना चाहिए" का मतलब है। भाषा या रनटाइम सिस्टम में कुछ भी नहीं है जो * आपको हैशकोड() 'और' बराबर() 'के लिए अनुबंध तोड़ने से रोकता है। लेकिन यदि आप करते हैं, तो आपके ऑब्जेक्ट पर हैशिंग का उपयोग करने वाली कोई भी चीज़ गलत तरीके से व्यवहार करेगी। –

1
for (int i=0; i < 10; i++) { 
    System.out.println("i: " + i + ", hashCode: " + new Object().hashCode()); 
} 

प्रिंट:


i: 0, hashCode: 1476323068 
i: 1, hashCode: 535746438 
i: 2, hashCode: 2038935242 
i: 3, hashCode: 988057115 
i: 4, hashCode: 1932373201 
i: 5, hashCode: 1001195626 
i: 6, hashCode: 1560511937 
i: 7, hashCode: 306344348 
i: 8, hashCode: 1211154977 
i: 9, hashCode: 2031692173 
+0

दिलचस्प। आप किस जेवीएम का उपयोग कर रहे हैं? –

+0

जावा-वर्जन: जावा संस्करण "1.6.0_20" जावा (टीएम) एसई रनटाइम पर्यावरण (1.6.0_20-बी 022) जावा हॉटस्पॉट (टीएम) 64-बिट सर्वर वीएम (बिल्ड 16.3-बी 01, मिश्रित मोड) –

2

जैसा कि मैंने कहीं पढ़ा है "... वस्तु स्तर पर, यह वस्तु की स्मृति पता देता है।"

यह कथन गलत है, या सबसे अच्छा एक ओवरम्प्लिफिकेशन है।

कथन Object.hashCode() के डिफ़ॉल्ट कार्यान्वयन का जिक्र कर रहा है जो System.identityHashcode(Object) के समान मान देता है।

Object.hashCode() के लिए जावाडोक कहना है कि यह:

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

और इस:

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

वास्तव में, पहचान hashCode मूल्य आम तौर पर वस्तु की मशीन पता के आधार पर जब विधि पहली वस्तु के लिए कहा जाता है। ऑब्जेक्ट हेडर में एक छिपे हुए फ़ील्ड में मान संग्रहीत किया जाता है। यह उसी हैशकोड को बाद की कॉल पर वापस करने की इजाजत देता है ... भले ही जीसी ने इस दौरान ऑब्जेक्ट को स्थानांतरित कर दिया हो।

ध्यान दें कि अगर किसी ऑब्जेक्ट के जीवनकाल में पहचान हैशकोड मान बदल गया है, तो यह hashcode() के अनुबंध का उल्लंघन करेगा, और हैशकोड के रूप में बेकार होगा।

3

hashCode() फ़ंक्शन को उसी निष्पादन में उसी ऑब्जेक्ट के लिए समान मान वापस करना चाहिए। विभिन्न निष्पादन के लिए समान मूल्य वापस करना आवश्यक नहीं है। निम्नलिखित टिप्पणियां देखें जो Object कक्षा से निकाली गई थीं।

hashCode के सामान्य अनुबंध है:

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

मैंने आपके कोड को कुछ बार निष्पादित किया है। यहाँ मेरी परिणाम

1935465023

1935465023

1935465023

1935465023

है 210

1935465023

1935465023

एक ही नंबर पर कई बार दोहराया जाता है। लेकिन इसका मतलब यह नहीं है कि वे हमेशा समान होते हैं। आइए मान लें, जेवीएम का एक विशेष कार्यान्वयन स्मृति में पहले फ्री स्लॉट की तलाश में है। तो यदि आप किसी अन्य अनुप्रयोग को नहीं चलाते हैं, तो उसी स्लॉट में ऑब्जेक्ट आवंटित करने की संभावना अधिक है।

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

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