2010-05-12 14 views
55

मैं सोच रहा था कि Java Map (HashMap या Hashtable) में जब वे जोड़े जाते हैं तो आइटम ऑर्डर करते हैं। क्या हैशकोड, मेमोरी रेफरेंस या आवंटन प्राथमिकता द्वारा क्रमबद्ध कुंजी हैं ...?जावा हैश मैप आइटम को हैश मैप या हैशटेबल में कैसे करता है?

क्योंकि मैं Map में एक ही जोड़े के देखा है यह उसी क्रम

उत्तर

112

java.util.HashMap अव्यवस्थित है की एक नहीं परिभाषित आदेश है; आप उससे परे कुछ भी नहीं मान सकते हैं और नहीं करना चाहिए।

यह कक्षा मानचित्र के आदेश के रूप में कोई गारंटी नहीं देती है; विशेष रूप से, यह गारंटी नहीं देता है कि आदेश समय के साथ स्थिर रहेगा।

java.util.LinkedHashMap सम्मिलन-आदेश का उपयोग करता है।

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

java.util.TreeMap, SortedMap, चाबियों के प्राकृतिक या कस्टम ऑर्डरिंग का उपयोग करता है।

नक्शा अपनी चाबियों का प्राकृतिक क्रम के अनुसार क्रमित है, या एक Comparator द्वारा नक्शा निर्माण समय में प्रदान की है, पर निर्भर करते हुए निर्माता प्रयोग किया जाता है।

+1

करता है फिर भी हैशमैप हर बार एक ही अनुमानित अनुक्रम का पालन करता है ... क्यों? –

+0

@ पॉप स्टैक हैश मैप आदेश की गारंटी नहीं देता है। Http://stackoverflow.com/questions/2144776/order-of-values-retrieved-from-a-hashmap पर स्टीफन सी का उत्तर देखें कि यह कैसे और क्यों बदल सकता है। –

+0

इस तरह के उत्तर बहुत अच्छे हैं! जावा में सभी मानचित्र, सूची, सेट के बीच मतभेदों को सूचीबद्ध करने के लिए एक धोखा शीट अद्भुत होगी! –

5

HashMap नहीं तरह बिल्कुल करता है में हमेशा नहीं कर रहे हैं। एक महत्वपूर्ण मानचित्र के आधार पर मानचित्र के लिए आपको TreeMap का उपयोग करना चाहिए।

TreeMap के लिए Javadocs से

: SortedMap इंटरफ़ेस का

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

HashMap के प्रलेखन से:

इस वर्ग नक्शे के आदेश के रूप में कोई गारंटी नहीं देता; विशेष रूप से, यह गारंटी नहीं देता है कि आदेश समय के साथ स्थिर रहेगा।

+0

मैंने कभी नहीं कहा था कि मैं उन्हें सॉर्ट करना चाहता हूं। मैं सोच रहा था कि जावा –

1

एक Map एक आदेश दिया डेटा संरचना नहीं है - आप एक निश्चित क्रम में किया जा रहा है एक HashMap में प्रविष्टियों पर भरोसा नहीं करना चाहिए। कुछ MapLinkedHashMap और TreeMap जैसे कार्यान्वयन एक निश्चित आदेश की गारंटी देते हैं, लेकिन HashMap नहीं है।

तुम सच में पता है कि आंतरिक रूप से होता है चाहते हैं, HashMap के स्रोत कोड देखने - आप src.zip जो आपके JDK स्थापना निर्देशिका में होना चाहिए में पा सकते हैं।

HashMap में कई "बाल्टी" हैं जिनमें यह अपनी प्रविष्टियों को संग्रहीत करता है। प्रविष्टि की कुंजी के हैश कोड द्वारा निर्धारित एक बाल्टी में प्रवेश किया जाता है। जिस क्रम में आप HashMap में प्रविष्टियां देखते हैं, वह कुंजी के हैश कोड पर निर्भर करता है। लेकिन उन कार्यक्रमों को न लिखें जो HashMap में एक निश्चित क्रम में होने वाली प्रविष्टियों पर भरोसा करते हैं - कार्यान्वयन जावा के भविष्य के संस्करण में बदल सकता है और आपका प्रोग्राम अब और काम नहीं करेगा।

0

हैश तालिका में कोई परिभाषित क्रम नहीं है। कुंजी को हैश कोड के आधार पर स्लॉट में रखा गया है, लेकिन यहां तक ​​कि यह एक छोटा ऑर्डर-बाय-हैश-कोड नहीं है।

14

सबसे पहले: HashMap विशेष रूप से एक स्थिर और/या परिभाषित आदेश प्रदान नहीं करता है। तो आप जो भी देखते हैं वह केवल एक कार्यान्वयन विवरण है और आप किसी भी तरह से इस पर निर्भर नहीं होना चाहिए।

एक HashMap (एक सरणी के रूप में लागू), जिसमें प्रविष्टियों स्टोर करने के लिए बकेट की संख्या है:

चूंकि यह कभी कभी मालूम होता है यादृच्छिक आदेश देने के लिए कारण जानना उपयोगी है, यहाँ मूल विचार है।

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

आग के अनुमानित क्रम (जैसे Map पर पुनरावृत्ति द्वारा लौटाया गया) उन बाल्टी में प्रविष्टियों के क्रम पर निर्भर करता है।

जब भी आकार को फिर से चलाया जाता है (क्योंकि नक्शा इसकी पूर्णता दहलीज से अधिक हो जाता है), तो बाल्टी की संख्या में परिवर्तन होता है, जिसका अर्थ है कि प्रत्येक तत्व की स्थिति बदल सकती है, क्योंकि बाल्टी स्थिति बाल्टी की संख्या से भी ली जाती है ।

0

हैश मैप कुंजी के एक हिस्से का उपयोग करके उत्पन्न अद्वितीय हैश-मान का उपयोग करके मानों को संग्रहीत करता है। यह हैश-वैल्यू मानचित्र उस पते पर है जहां इसे संग्रहीत किया जा रहा है। इस तरह यह ओ (1) तक पहुंच सुनिश्चित करता है।

दूसरी ओर लिंक्ड हैशमैप उस क्रम को संरक्षित करता है जिसमें आपने मानचित्र में जोड़ा था।

+1

हैश मैप ओ (1) की गारंटी नहीं दे सकता है। यह इसके बारे में सबसे अच्छा करने की कोशिश करता है, लेकिन सबसे बुरे मामले में यह ओ (एन) एन = प्रविष्टियों की संख्या के साथ है (भले ही यह असंभव है (या यदि आपकी हैशकोड विधि वास्तव में खराब है)) – Hardcoded

+0

सहमत है कि यह हमेशा प्रदान नहीं करता है निरंतर समय का प्रदर्शन, लेकिन अधिक से अधिक नहीं, यह करने का प्रयास करता है। http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html –

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