2012-06-05 9 views
9

मुझे समझ में आता है कि मेमोरी एड्रेस में अपना मान स्टोर करने के लिए एक हैशिंग तकनीक लागू की गई है।स्मृति में हैशटेबल और हैश मैप कुंजी-मूल्य कैसे संग्रहीत किए जाते हैं?

लेकिन मुझे समझ में नहीं आता है कि टकराव कैसे हो रहा है? जावा हैशिंग एल्गोरिदम जावा मेमोरी स्पेस बनाने के लिए उपयोग करता है? क्या यह एमडी 5 है?

उत्तर

22

HashMap के मूल विचार यह है:

  1. एक HashMap वास्तव में विशेष वस्तुओं है कि दोनों कुंजी और मान पकड़ की एक सरणी है।
  2. सरणी, बाल्टी (स्लॉट) की कुछ राशि है का कहना है कि 16
  3. हैशिंग एल्गोरिथ्म हर वस्तु है कि hashCode() विधि द्वारा प्रदान की जाती है। इसलिए, जब आप एक नया Class लिख रहे हैं, तो आपको उचित hashCode() और equals() विधियों के कार्यान्वयन का ख्याल रखना चाहिए। डिफ़ॉल्ट एक (Object वर्ग का) स्मृति सूचक को एक संख्या के रूप में लेता है। लेकिन यह उन वर्गों के लिए अच्छा नहीं है जिन्हें हम उपयोग करना चाहते हैं। उदाहरण के लिए, String कक्षा एक एल्गोरिदम का उपयोग करती है जो स्ट्रिंग में सभी वर्णों से हैश बनाता है - इसे इस तरह सोचें: hashCode = 1.char + 2.char + 3.char... (सरलीकृत)। इसलिए, दो बराबर स्ट्रिंग्स, भले ही वे स्मृति में एक अलग स्थान पर हैं, वही hashCode() है।
  4. hashCode() का परिणाम, "132" कहें, तो बाल्टी की संख्या है जहां ऑब्जेक्ट को संग्रहीत किया जाना चाहिए यदि हमारे पास बड़ी सरणी थी। लेकिन हम नहीं करते हैं, हमारा केवल 16 बाल्टी लंबा है। इसलिए हम स्पष्ट गणना 'hashcode % array.length = bucket' या '132 mod 16 = 4' का उपयोग करें और अगर कोई अन्य जोड़ी अभी तक है कुंजी-मान पेयर एक बाल्टी संख्या में 4.
    • की दुकान, यह ठीक है।
    • यदि हमारे पास कुंजी के बराबर कुंजी है, तो हम पुराने को हटा देते हैं।
    • यदि कोई अन्य कुंजी-मूल्य जोड़ी (टकराव) है, तो हम पुरानी एक को एक लिंक्ड सूची में ले जाने के बाद नई श्रृंखला को चेन करते हैं।
  5. समर्थन सरणी भी भरा हो जाता है, तो हम भी कई जुड़ा हुआ सूचियों बनाने के लिए हम दोगुनी लंबाई के साथ एक नई सरणी बनाने के लिए होता है, सभी तत्वों को मिला देना और उन्हें नए सरणी में जोड़ने के लिए, तो हम निपटाने पुराना वाला।यह HashMap पर सबसे महंगा ऑपरेशन है, इसलिए आप अपने Maps को बताना चाहते हैं कि यदि आप इसे पहले जानते हैं तो आप कितनी बाल्टी का उपयोग करेंगे।
  6. यदि कोई व्यक्ति मूल्य प्राप्त करने का प्रयास करता है, तो वह एक कुंजी प्रदान करता है, हम इसे हैश करते हैं, इसे संशोधित करते हैं, और फिर सटीक मिलान के लिए संभावित लिंक्ड सूची में जाते हैं।

An image, courtesy of Wikipedia: The graphics

इस मामले में,

  • 256 बाल्टी (गिने, ज़ाहिर है, 0-255)
  • पांच लोगों को देखते हैं के साथ एक सरणी है। उनके हैशकोड, mod 256 के माध्यम से डालने के बाद, सरणी में चार अलग-अलग स्लॉट इंगित करें।
  • आप देख सकते हैं कि सैंड्रा डी के पास मुफ्त स्लॉट नहीं था, इसलिए जॉन स्मिथ के बाद उसे जंजीर कर दिया गया।

अब, अगर आपने सैंड्रा डी के टेलीफोन नंबर को देखने का प्रयास किया है, तो आप उसका नाम होगा, इसे 256 तक संशोधित करें, और बाल्टी 152 में देखें। वहां आपको जॉन स्मिथ मिलेगा। यह कोई सैंड्रा नहीं है, आगे देखो ... आह, सैंड्रा जॉन के बाद जंजीर है।

+0

यदि आपको छवियों के साथ समझाया गया कोई भी लिंक मिलता है तो कृपया इसे यहां रखें .. यह बहुत उपयोगी होगा .. – Sahal

+1

हो गया। यह [विकिपीडिया में इस लेख] से है (http://en.wikipedia.org/wiki/Hash_table#Separate_chaining_with_list_heads)। –

+1

और अब, जब आप इसे जानते हैं, [यह 'स्ट्रिंग' असली' हैशकोड() 'कार्यान्वयन] है (http://docs.oracle.com/javase/7/docs/api/java/lang/ String.html # hashCode% 28% 29)। [और] (http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier) [कुछ] (http://stackoverflow.com/ प्रश्न/1835 9 76/क्या-एक-समझदार-प्राइम-फॉर हैशकोड-गणना) [यादृच्छिक] (http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode) 'हैशकोड()' में प्राइम नंबर चयन पर लिंक। –

2

डिफ़ॉल्ट कार्यान्वयन के रूप में Object कक्षा में hashCode() समारोह हैश जो HashTable & HashMap में कुंजी के रूप में प्रयोग किया जाता है के रूप में स्मृति पता वापस।

+0

उदाहरण के लिए यदि आपके पास हैशटेबल में 100 रिकॉर्ड हैं, और आप 'मेन इन ब्लैक' के साथ एक कुंजी खोजना चाहते हैं, तो इसका मूल्य कितना तेज़ हो जाता है? मुझे लगता है कि इसे खोजने के लिए एक से अधिक पुनरावृत्ति नहीं ले पाएंगे क्यू (1)। मुझे लगा कि कंपाइलर 'मेन इन ब्लैक' का हैशकोड बनाता है और यह उस विशेष स्मृति स्थान में मान संग्रहीत करता है। बाद में जब हम इसे पुनः प्राप्त करने का प्रयास करते हैं, तो यह इसके मूल्य को खोजने के लिए हैकोड का उपयोग करता है ..... क्या मुझे कुछ याद आ रहा है? .... यदि ऐसा नहीं है तो कुंजी खोज का रन टाइम एक यानी है। (1)? – Sahal

+1

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

+0

इसके अलावा, 'स्ट्रिंग' वर्ग में इसका अपना 'हैशकोड() 'कार्यान्वयन है, यह स्मृति स्थान को इसके रूप में नहीं लेता है, लेकिन स्ट्रिंग में वास्तविक वर्णों से हैश बनाने के लिए एल्गोरिदम का उपयोग करता है ... –

4

यहां HashHashing तकनीकों जैसे MD5 के लिए इसका मतलब नहीं है। किसी विशेष कुंजी के लिए Object स्टोर करने के लिए उपयोग की गई मेमोरी लोकेशन का HashCode है।

रीडिंग:

This कुछ और अधिक HashMap कैसे काम करता है की स्पष्ट व्याख्या है?

+0

उदाहरण के लिए यदि आपके पास हैशटेबल में 100 रिकॉर्ड हैं, और आप 'मेन इन ब्लैक' के साथ एक कुंजी खोजना चाहते हैं, तो इसका मूल्य कितना तेज़ हो जाता है? मुझे लगता है कि इसे खोजने के लिए एक से अधिक पुनरावृत्ति नहीं ले पाएंगे क्यू (1)। मुझे लगा कि कंपाइलर 'मेन इन ब्लैक' का हैशकोड बनाता है और यह उस विशेष स्मृति स्थान में मान संग्रहीत करता है। बाद में जब हम इसे पुनः प्राप्त करने का प्रयास करते हैं, तो यह इसके मूल्य को खोजने के लिए हैकोड का उपयोग करता है ..... क्या मुझे कुछ याद आ रहा है? .... यदि ऐसा नहीं है तो कुंजी खोज का रन टाइम एक यानी है। (1)? – Sahal

+0

पढ़ें कि अद्यतन लिंक – Asif

+2

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

1

@ स्लेनेक के उत्तर के माध्यम से जाने के बाद, जावा -8 से जावाडोक देखें, क्योंकि इसमें महत्वपूर्ण बदलाव हैं। पूर्व के लिए: 'TREEIFY' जहां लिंक्डलिस्ट को एक बाल्टी मैप में परिवर्तित किया जाता है, यदि प्रति बाल्टी प्रविष्टियों की दहलीज संख्या (वर्तमान में 8) तक पहुंच जाती है।