जावा में a HashMap
और a के बीच अंतर क्या हैं Hashtable
?
गैर-थ्रेडेड अनुप्रयोगों के लिए कौन सा अधिक कुशल है?
ConcurrentMap
है न आवश्यक यहाँ, के रूप में प्रश्न कहते हैं, "गैर पिरोया अनुप्रयोगों" अर्थ सूत्रण / संगामिति कोई मुद्दा नहीं है।
जावा में a HashMap
और a के बीच अंतर क्या हैं Hashtable
?
गैर-थ्रेडेड अनुप्रयोगों के लिए कौन सा अधिक कुशल है?
ConcurrentMap
है न आवश्यक यहाँ, के रूप में प्रश्न कहते हैं, "गैर पिरोया अनुप्रयोगों" अर्थ सूत्रण / संगामिति कोई मुद्दा नहीं है।
जवाबों:
जावा में HashMap
और इसके बीच कई अंतर हैं Hashtable
:
Hashtable
है सिंक्रनाइज़ , जबकि HashMap
नहीं है। यह HashMap
गैर-थ्रेडेड अनुप्रयोगों के लिए बेहतर बनाता है, क्योंकि असंबद्ध वस्तुएं आमतौर पर सिंक्रनाइज़ किए गए लोगों की तुलना में बेहतर प्रदर्शन करती हैं।
Hashtable
null
चाबियाँ या मूल्यों की अनुमति नहीं देता है । HashMap
एक null
कुंजी और किसी भी null
मान की अनुमति देता है ।
हाशपॉफ़ के उपवर्गों में से एक है LinkedHashMap
, इसलिए इस घटना में कि आप पूर्वानुमानित पुनरावृत्ति क्रम चाहते हैं (जो डिफ़ॉल्ट रूप से प्रविष्टि क्रम है), आप आसानी से HashMap
एक के लिए स्वैप कर सकते हैं LinkedHashMap
। यदि आप उपयोग कर रहे थे तो यह उतना आसान नहीं होगा Hashtable
।
चूंकि सिंक्रोनाइज़ेशन आपके लिए कोई समस्या नहीं है, इसलिए मैं सुझाव दूंगा HashMap
। यदि सिंक्रनाइज़ेशन एक मुद्दा बन जाता है, तो आप भी देख सकते हैं ConcurrentHashMap
।
Collections.synchronizedMap()
।
Hashtable
("हर विधि को सिंक्रनाइज़ करने में किसी भी संगामिति समस्याओं का ध्यान रखना चाहिए!") के लिए भोली दृष्टिकोण थ्रेडेड अनुप्रयोगों के लिए बहुत बुरा बनाता है । आप बाह्य रूप से बेहतर HashMap
(और परिणामों के बारे में सोच रहे हैं) को सिंक्रनाइज़ कर रहे हैं , या ConcurrentMap
कार्यान्वयन का उपयोग कर रहे हैं (और संगोष्ठी के लिए विस्तारित एपीआई का शोषण कर रहे हैं)। नीचे पंक्ति: उपयोग करने का एकमात्र कारण Hashtable
तब है जब एक लीगेसी एपीआई (सीए 1996 से) की आवश्यकता होती है।
ध्यान दें, कि बहुत सारे उत्तर बताते हैं कि हैशटेबल सिंक्रनाइज़ है। व्यवहार में यह आपको बहुत कम खरीदता है। सिंक्रोनाइज़ेशन एक्सेसर / म्यूटेटर विधियों पर होता है, दो थ्रेड्स को नक्शे से समवर्ती रूप से जोड़ने या हटाने से रोक देगा, लेकिन वास्तविक दुनिया में आपको अक्सर अतिरिक्त सिंक्रनाइज़ेशन की आवश्यकता होगी।
एक बहुत ही सामान्य मुहावरा है "जांचना फिर डाल देना" - यानी इसमें प्रवेश की तलाश करें Map
और इसे जोड़ें अगर यह पहले से मौजूद नहीं है। यह किसी भी तरह से एक परमाणु ऑपरेशन नहीं है चाहे आप उपयोग करें Hashtable
याHashMap
।
एक समतुल्य सिंक्रनाइज़ HashMap
द्वारा प्राप्त किया जा सकता है:
Collections.synchronizedMap(myMap);
लेकिन इस तर्क को सही ढंग से लागू करने के लिए आपको फॉर्म के अतिरिक्त सिंक्रनाइज़ेशन की आवश्यकता है :
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
यहां तक कि जब तक आप अतिरिक्त सिंक्रनाइज़ेशन के माध्यम से संशोधित होने से भी रक्षा नहीं करते हैं, तब तक Hashtable
एक (या HashMap
द्वारा प्राप्त Collections.synchronizedMap
) से अधिक पुनरावृत्ति करना सुरक्षित नहीं है Map
।
ConcurrentMap
इंटरफ़ेस का कार्यान्वयन (उदाहरण के लिए ConcurrentHashMap
) थ्रेड सेफ चेक-तत्कालीन एक्ट शब्दार्थों को शामिल करके इनमें से कुछ को हल करें :
ConcurrentMap.putIfAbsent(key, value);
Hashtable
विरासत कोड माना जाता है। इस बारे में कुछ भी नहीं है Hashtable
कि इसका उपयोग HashMap
या व्युत्पन्न नहीं किया जा सकता है HashMap
, इसलिए नए कोड के लिए, मुझे वापस जाने का कोई औचित्य नहीं दिखता है Hashtable
।
यह सवाल अक्सर साक्षात्कार में पूछा जाता है कि क्या उम्मीदवार संग्रह कक्षाओं के सही उपयोग को समझता है और उपलब्ध वैकल्पिक समाधानों से अवगत है।
HashMap
वर्ग मोटे तौर पर के बराबर है Hashtable
, सिवाय इसके कि यह गैर सिंक्रनाइज़ और परमिट nulls है। ( HashMap
कुंजी और मान के रूप में शून्य मानों की अनुमति देता है जबकि Hashtable
अनुमति नहीं देता हैnull
)।HashMap
यह गारंटी नहीं देता है कि नक्शे का क्रम समय के साथ स्थिर रहेगा।HashMap
गैर सिंक्रनाइज़ है जबकि Hashtable
सिंक्रनाइज़ किया गया है।HashMap
फेल-सेफ थोड़ी देर के लिए प्रगणक है Hashtable
नहीं है और फेंक ConcurrentModificationException
अगर किसी अन्य थ्रेड संशोधित मानचित्र संरचनात्मक रूप से जोड़ने या को छोड़कर किसी भी तत्व को हटाने के द्वारा Iterator
की खुद की remove()
विधि। लेकिन यह एक गारंटीकृत व्यवहार नहीं है और सबसे अच्छे प्रयास पर जेवीएम द्वारा किया जाएगा।कुछ महत्वपूर्ण शर्तों पर ध्यान दें:
Hashtable
वसीयत को ऑब्जेक्ट पर लॉक हासिल करना होगा जबकि अन्य लॉक जारी होने का इंतजार करेंगे।set
विधियों के लिए यह संभव है कि विधि को लागू किया जाए क्योंकि यह संग्रह को "संरचनात्मक रूप से" संशोधित नहीं करता है। हालांकि, यदि कॉल करने से पहले set
, संग्रह को संरचनात्मक रूप से संशोधित किया गया है, IllegalArgumentException
तो इसे फेंक दिया जाएगा।HashMap
द्वारा सिंक्रनाइज़ किया जा सकता है
Map m = Collections.synchronizeMap(hashMap);
मैप एन्यूमेंटेशन ऑब्जेक्ट्स के माध्यम से पुनरावृत्ति के लिए सीधे समर्थन के बजाय संग्रह दृश्य प्रदान करता है। इस अनुभाग में बाद में चर्चा की गई के अनुसार संग्रह के विचार, इंटरफ़ेस की अभिव्यक्ति को बहुत बढ़ाते हैं। मानचित्र आपको कुंजियों, मूल्यों या कुंजी-मूल्य जोड़े पर पुनरावृति करने की अनुमति देता है;
Hashtable
तीसरा विकल्प प्रदान नहीं करता है। मानचित्र पुनरावृति के बीच में प्रविष्टियों को हटाने का एक सुरक्षित तरीका प्रदान करता है; Hashtable
नहीं किया। अंत में, मानचित्र Hashtable
इंटरफ़ेस में एक छोटी सी कमी को ठीक करता है ।
Hashtable
इसमें एक विधि शामिल है, जो Hashtable
किसी दिए गए मान में सही होने पर वापस आती है
। इसके नाम को देखते हुए, यदि आप Hashtable
किसी दिए गए कुंजी को निहित करते हैं, तो आप इस विधि के सही होने की उम्मीद करेंगे , क्योंकि कुंजी प्राथमिक एक्सेस तंत्र है a Hashtable
। नक्शा इंटरफ़ेस विधि का नाम बदलकर भ्रम के इस स्रोत को समाप्त करता है
containsValue
। इसके अलावा, यह इंटरफेस की containsValue
समानता में सुधार करता है -
समानताएं containsKey
।
set
ऑपरेशन नहीं है a HashMap
। 3) यदि कोई पिछला परिवर्तन था, तो put(...)
ऑपरेशन नहीं फेकेगा IllegalArgumentException
। 4) यदि आप मैपिंग बदलते हैं तो असफल-तेज़ व्यवहार HashMap
भी होता है। 5) असफल-तेज़ व्यवहार की गारंटी है। (जो गारंटी नहीं दी जाती है HashTable
यदि आप एक समवर्ती संशोधन करते हैं, तो व्यवहार वास्तविक है ... अप्रत्याशित है।)
Hashtable
यह गारंटी नहीं देता है कि मानचित्र तत्वों का क्रम समय के साथ स्थिर होगा। (आप शायद भ्रमित कर रहे हैं Hashtable
के साथ LinkedHashMap
।)
thing.set(thing.get() + 1);
जो अधिक बार पूरी तरह से असुरक्षित रूप से आश्चर्यचकित होकर नए-नए नहीं पकड़ता है, खासकर अगर get()
और set()
सिंक्रनाइज़ तरीके हैं। उनमें से कई जादू की उम्मीद कर रहे हैं।
HashMap
: Map
किसी सरणी को अनुक्रमित करने के लिए हैश कोड का उपयोग करने वाले इंटरफ़ेस का कार्यान्वयन ।
Hashtable
: हाय, 1998 कहा जाता है। वे अपने संग्रह एपीआई वापस चाहते हैं।
गंभीरता से, आप Hashtable
पूरी तरह से दूर रहने से बेहतर हैं। एकल-थ्रेडेड एप्लिकेशन के लिए, आपको सिंक्रनाइज़ेशन के अतिरिक्त ओवरहेड की आवश्यकता नहीं है। अत्यधिक समवर्ती ऐप्स के लिए, पैरानॉयड सिंक्रोनाइज़ेशन से भुखमरी, गतिरोध या अनावश्यक कचरा संग्रह रुक सकता है। टिम हावलैंड ने बताया, आप ConcurrentHashMap
इसके बजाय उपयोग कर सकते हैं ।
ध्यान रखें कि HashTable
जावा कलेक्शंस फ्रेमवर्क (JCF) शुरू होने से पहले विरासत वर्ग था और Map
इंटरफ़ेस को लागू करने के लिए बाद में रेट्रोफिट किया गया था । तो था Vector
और Stack
।
इसलिए, नए कोड में हमेशा उनसे दूर रहें क्योंकि जेसीएफ में हमेशा बेहतर विकल्प होता है क्योंकि अन्य लोगों ने बताया था।
यहां जावा संग्रह धोखा शीट है जो आपको उपयोगी मिलेगा। गौर करें कि ग्रे ब्लॉक में विरासत श्रेणी हैशटेबल, वेक्टर और स्टैक शामिल हैं।
कई अच्छे उत्तर पहले से ही पोस्ट किए गए हैं। मैं कुछ नए बिंदु जोड़ रहा हूं और इसे संक्षेप में बता रहा हूं।
HashMap
और Hashtable
दोनों का उपयोग डेटा को कुंजी और मान के रूप में संग्रहीत करने के लिए किया जाता है । दोनों अद्वितीय कुंजियों को संग्रहीत करने के लिए हैशिंग तकनीक का उपयोग कर रहे हैं। लेकिन हाशप और हैशटेबल वर्गों के बीच कई अंतर हैं जो नीचे दिए गए हैं।
हैश मैप
HashMap
गैर सिंक्रनाइज़ है। यह थ्रेड-थ्रेड सुरक्षित नहीं है और उचित सिंक्रनाइज़ेशन कोड के बिना कई थ्रेड्स के बीच साझा नहीं किया जा सकता है। HashMap
एक अशक्त कुंजी और कई अशक्त मूल्यों की अनुमति देता है। HashMap
JDK 1.2 में पेश किया गया एक नया वर्ग है। HashMap
तेज़ है। HashMap
इस कोड को कॉल करके के रूप में सिंक्रनाइज़ कर सकते हैंMap m = Collections.synchronizedMap(HashMap);
HashMap
Iterator द्वारा ट्रैवर्स किया गया है। HashMap
विफल-तेज है। HashMap
सार वर्ग वर्ग विरासत में मिला है। हैश टेबल
Hashtable
सिंक्रनाइज़ किया गया है। यह थ्रेड-सुरक्षित है और इसे कई थ्रेड्स के साथ साझा किया जा सकता है। Hashtable
किसी भी अशक्त कुंजी या मूल्य की अनुमति नहीं देता है। Hashtable
एक विरासत वर्ग है। Hashtable
धीमा है। Hashtable
आंतरिक रूप से सिंक्रोनाइज़ किया गया है और इसे अनसिंक्रनाइज़ नहीं किया जा सकता है। Hashtable
Enumerator और Iterator द्वारा ट्रैवर्स किया गया है। Hashtable
फेल-फास्ट नहीं है। Hashtable
शब्दकोश वर्ग विरासत में मिला।आगे पढ़ते हैं कि HashMap और Hashtable in Java में क्या अंतर है?
Izb ने जो कहा, इसके अलावा, HashMap
शून्य मानों की अनुमति देता है, जबकि Hashtable
ऐसा नहीं है।
यह भी ध्यान दें कि कक्षा का Hashtable
विस्तार Dictionary
, जो कि जावदोस्क राज्य के रूप में है, अप्रचलित है और इसे Map
इंटरफ़ेस द्वारा बदल दिया गया है।
इस चार्ट पर एक नजर डालें। यह अलग-अलग डेटा संरचनाओं के साथ HashMap
और साथ तुलना प्रदान करता है Hashtable
। तुलना सटीक, स्पष्ट और समझने में आसान है।
Hashtable
के समान है HashMap
और एक समान इंटरफ़ेस है। यह अनुशंसा की जाती है कि आप उपयोग करते हैं HashMap
, जब तक कि आपको विरासत अनुप्रयोगों के लिए समर्थन की आवश्यकता नहीं होती है या आपको सिंक्रनाइज़ेशन की आवश्यकता होती है, क्योंकि Hashtables
विधियों को सिंक्रनाइज़ किया जाता है। तो आपके मामले में जैसे आप मल्टी-थ्रेडिंग नहीं कर रहे हैं, HashMaps
क्या आपकी सबसे अच्छी शर्त है।
हैशटेबल और हैशमैप के बीच एक और महत्वपूर्ण अंतर यह है कि हैशटेबल में इटरेटर फेल-फास्ट है, जबकि हैशटेबल के लिए एन्यूमरेटर नहीं है और कंसंट्रेटमोडिफिकेशन अपवाद को नहीं फेंकें यदि कोई अन्य थ्रेड मैप में किसी तत्व को जोड़ने या हटाने के लिए संरचनात्मक रूप से संशोधित करता है सिवाय इटरेटर के खुद के हटाने () विधि को। लेकिन यह एक गारंटीकृत व्यवहार नहीं है और जेवीएम द्वारा सर्वश्रेष्ठ प्रयास पर किया जाएगा। ”
मेरा स्रोत: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
पहले से ही यहां बताए गए अन्य सभी महत्वपूर्ण पहलुओं के अलावा, कलेक्शन एपीआई (उदाहरण के लिए इंटरफ़ेस) को जावा कल्पना के "नवीनतम और सबसे बड़े" परिवर्धन के अनुरूप हर समय संशोधित किया जा रहा है।
उदाहरण के लिए, Java 5 मैप की तुलना करें:
for (Elem elem : map.keys()) {
elem.doSth();
}
बनाम पुराने हैशटेबल दृष्टिकोण:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
जावा 1.8 में हम अच्छी पुरानी स्क्रिप्टिंग भाषाओं की तरह हैशमैप के निर्माण और उपयोग करने में सक्षम होने का भी वादा करते हैं:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
अद्यतन: नहीं, वे 1.8 में नहीं उतरेंगे ... :(
क्या प्रोजेक्ट कॉइन के कलेक्शन में बढ़ोतरी JDK8 में होने वाली है?
हैशटेबल को सिंक्रनाइज़ किया गया है, यदि आप इसे एक ही धागे में उपयोग कर रहे हैं तो आप उपयोग कर सकते हैं HashMap का , जो कि एक अनसंकटेड संस्करण है। असंसाधित वस्तुएं अक्सर थोड़ी अधिक होती हैं। वैसे यदि कई थ्रेड्स एक हाशपॅम को समवर्ती रूप से एक्सेस करते हैं, और कम से कम एक थ्रेड संरचनात्मक रूप से मानचित्र को संशोधित करता है, तो इसे बाहरी रूप से सिंक्रनाइज़ किया जाना चाहिए। यूं एक असम्बद्ध सिंक्रनाइज़्ड मैप को एक सिंक्रनाइज़ एक में लपेट कर उपयोग कर सकते हैं:
Map m = Collections.synchronizedMap(new HashMap(...));
हैशटेबल में केवल कुंजी के रूप में या मान के रूप में गैर-अशक्त वस्तु हो सकती है। HashMap में एक शून्य कुंजी और अशक्त मान हो सकते हैं।
मैप द्वारा लौटाए गए पुनरावृत्तियाँ विफल-तेज़ हैं, यदि इट्रेटर बनने के बाद किसी भी समय मैप को संरचनात्मक रूप से संशोधित किया जाता है, तो किसी भी तरह से इटरेटर की स्वयं की हटाने की विधि के अलावा, इटरेटर को फेंक देगा ConcurrentModificationException
। इस प्रकार, समवर्ती संशोधन के सामने, भविष्य में एक अनिर्धारित समय पर मनमाना, गैर-निर्धारक व्यवहार को जोखिम में डालने के बजाय, यह जल्दी और साफ-सुथरा हो जाता है। जबकि हैशटेबल की कुंजियों और तत्वों के तरीकों से लौटे एन्युमरेशन्स फेल-फास्ट नहीं हैं।
HashTable और HashMap के सदस्य हैं जावा कलेक्शन फ्रेमवर्क के (जावा 2 प्लेटफॉर्म v1.2 के बाद से, हैशटेबल को मैप इंटरफेस को लागू करने के लिए रेट्रोफिट किया गया था)।
हैशटेबल को विरासत कोड माना जाता है, प्रलेखन उपयोग करने की सलाह देता है हैशटेबल के स्थान पर समवर्ती हाशपे यदि थ्रेड-सुरक्षित अति-समवर्ती कार्यान्वयन वांछित है।
HashMap उस आदेश की गारंटी नहीं देता जिसमें तत्व वापस किए जाते हैं। हैशटेबल के लिए मुझे लगता है कि यह समान है, लेकिन मुझे पूरी तरह से यकीन नहीं है, मुझे लगता है कि स्पष्ट रूप से उस स्थिति को पुनः प्राप्त नहीं करते हैं।
HashMap
और Hashtable
महत्वपूर्ण एल्गोरिथम अंतर भी हैं। इससे पहले किसी ने इसका उल्लेख नहीं किया इसलिए मैं इसे ला रहा हूं। HashMap
दो आकार की शक्ति के साथ एक हैश टेबल का निर्माण करेगा, इसे गतिशील रूप से बढ़ाएगा जैसे आपके पास किसी भी बाल्टी में लगभग आठ तत्व (टकराव) हैं और तत्वों को सामान्य तत्व प्रकारों के लिए बहुत अच्छी तरह से हिलाएंगे। हालांकिHashtable
कार्यान्वयन हैशिंग पर बेहतर और बेहतर नियंत्रण प्रदान करता है यदि आप जानते हैं कि आप क्या कर रहे हैं, तो आप अपने मान डोमेन आकार के निकटतम प्राइम संख्या का उपयोग करके तालिका आकार को ठीक कर सकते हैं और इसके परिणामस्वरूप हाशप की तुलना में बेहतर प्रदर्शन होगा अर्थात कम टकराव कुछ मामलों के लिए।
इस प्रश्न में व्यापक रूप से चर्चा किए गए स्पष्ट अंतरों से अलग, मैं हैशटेबल को एक "मैनुअल ड्राइव" कार के रूप में देखता हूं जहां आपके पास हैशिंग और हैशपॉप पर "स्वचालित ड्राइव" समकक्ष के रूप में बेहतर नियंत्रण है जो आमतौर पर अच्छा प्रदर्शन करेंगे।
यहाँ जानकारी के आधार पर , मैं HashMap के साथ जाने की सलाह दूंगा। मुझे लगता है कि सबसे बड़ा फायदा यह है कि जावा आपको इसे संशोधित करने से रोकेगा, जब तक आप इसे इट्रेटर के माध्यम से नहीं करते हैं।
ए Collection
- कभी-कभी कंटेनर कहा जाता है - बस एक वस्तु है जो कई तत्वों को एक इकाई में समूहित करता है। Collection
s का उपयोग कुल डेटा को संग्रहीत करने, पुनः प्राप्त करने, हेरफेर करने और संचार करने के लिए किया जाता है। एक संग्रह फ्रेमवर्क डब्ल्यू प्रतिनिधित्व करने और हेरफेर करने के लिए एक एकीकृत वास्तुकला है।
HashMap
JDK1.2
और Hashtable JDK1.0
, दोनों वस्तुओं है कि में प्रतिनिधित्व कर रहे हैं के एक समूह का प्रतिनिधित्व करने के लिए उपयोग किया जाता <Key, Value>
जोड़ी। प्रत्येक <Key, Value>
जोड़ी को Entry
ऑब्जेक्ट कहा जाता है। प्रविष्टियों का संग्रह की वस्तु से जाना जाता है HashMap
और Hashtable
। एक संग्रह की कुंजी विशिष्ट या विशिष्ट होनी चाहिए। [के रूप में वे एक विशेष मूल्य एक प्रतिचित्रित मूल्य को प्राप्त करने के लिए उपयोग किया जाता है। एक संग्रह में मूल्यों को दोहराया जा सकता है।]
« सुपरक्लास, लिगेसी और कलेक्शन फ्रेमवर्क सदस्य
हैशटेबल एक विरासत श्रेणी है जिसे शुरू किया गया JDK1.0
, जो कि शब्दकोश वर्ग का एक उपवर्ग है। से JDK1.2
Hashtable लागू करने के लिए फिर से इंजीनियर है मानचित्र इंटरफ़ेस संग्रह ढांचे के एक सदस्य बनाने के लिए। HashMap अपने संग्रह की शुरुआत से ही जावा संग्रह फ्रेमवर्क का एक सदस्य है JDK1.2
। HashMap AbstractMap वर्ग का उपवर्ग है।
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« प्रारंभिक क्षमता और लोड कारक
क्षमता हैश तालिका में बाल्टी की संख्या है, और प्रारंभिक क्षमता बस उस समय क्षमता है जब हैश तालिका बनाई जाती है। ध्यान दें कि हैश तालिका खुली है: " hash
collision
" के मामले में , एक एकल बाल्टी कई प्रविष्टियों को संग्रहीत करती है, जिसे क्रमिक रूप से खोजा जाना चाहिए। लोड फैक्टर इस बात का एक पैमाना है कि कैसे हैश तालिका को पूर्ण करने की अनुमति दी जाती है इससे पहले कि इसकी क्षमता अपने आप बढ़ जाए।
HashMap डिफ़ॉल्ट प्रारंभिक क्षमता (16) के साथ एक खाली हैश तालिका का निर्माण करता है और डिफ़ॉल्ट लोड कारक (0.75) के । जहां हैशटेबल डिफ़ॉल्ट प्रारंभिक क्षमता (11) और लोड फैक्टर / भराव अनुपात (0.75) के साथ खाली हैशटेब का निर्माण करता है ।
« हैश टक्कर के मामले में संरचनात्मक संशोधन
HashMap
, Hashtable
हैश टक्कर के मामले में वे लिंक प्रविष्टियों में मानचित्र प्रविष्टियों को संग्रहीत करते हैं। के लिए Java8 सेHashMap
अगर हैश बाल्टी एक निश्चित सीमा से आगे बढ़ती है, तो वह बाल्टी से स्विच हो जाएगी । जो ओ (एन) से ओ (लॉग एन) से सबसे खराब स्थिति के प्रदर्शन में सुधार करता है। सूची को बाइनरी ट्री में परिवर्तित करते समय, हैशकोड का उपयोग ब्रांचिंग चर के रूप में किया जाता है। यदि एक ही बाल्टी में दो अलग-अलग हैशकोड हैं, तो एक बड़ा माना जाता है और पेड़ के दाईं ओर और दूसरा एक बाईं ओर जाता है। लेकिन जब दोनों हैशकोड समान होते हैं, तो माना जाता है कि चाबियाँ तुलनीय हैं, और कुंजी को दिशा निर्धारित करने के लिए तुलना करता है ताकि कुछ आदेश बनाए रखा जा सके। तुलनीय की कुंजी बनाने के लिए यह एक अच्छा अभ्यास है । यदि बकेट का आकार पहुँचता है तो प्रविष्टियाँ जोड़ने पर और अधिक से अधिक प्रविष्टियों की लिंक की गई सूची के लिए संतुलित पेड़ को वापस कर देगा। जावा 8 एसआरसीlinked list of entries to a balanced tree
HashMap
HashMap
TREEIFY_THRESHOLD = 8
प्रविष्टियों की लिंक की गई सूची को एक संतुलित पेड़ में परिवर्तित करें, प्रविष्टियों को कम से कम हटाने पर , स्टैकपोस्टTREEIFY_THRESHOLD
UNTREEIFY_THRESHOLD = 6
« संग्रह-दृश्य पुनरावृत्ति, विफल-फास्ट और विफल-सुरक्षित
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
प्रकृति में एक असफल-उपवास है। अगर यह एक संग्रह को संशोधित करने के अलावा अन्य है, तो यह समवर्तीModificationException फेंकता है। जहां Enumeration
प्रकृति में असफल-सुरक्षित है। यदि पुनरावृति करते समय कोई संग्रह संशोधित किया जाता है तो यह कोई अपवाद नहीं फेंकता है।
जावा एपीआई डॉक्स के अनुसार, Iterator को हमेशा Enumeration से अधिक पसंद किया जाता है।
ध्यान दें: गणना इंटरफ़ेस की कार्यक्षमता Iterator इंटरफ़ेस द्वारा दोहराई गई है। इसके अलावा, Iterator एक वैकल्पिक निष्कासन ऑपरेशन जोड़ता है, और इसमें कम विधि नाम होते हैं। गणना के लिए नए कार्यान्वयन को Iterator का उपयोग करने पर विचार करना चाहिए।
में जावा 5 पेश किया ConcurrentMap इंटरफ़ेस : ConcurrentHashMap
- एक उच्च समवर्ती, उच्च प्रदर्शन ConcurrentMap
कार्यान्वयन एक हैश तालिका पर आधारित। पुनर्प्राप्ति करते समय यह कार्यान्वयन कभी भी अवरुद्ध नहीं होता है और क्लाइंट को अपडेट के लिए संगामिति स्तर का चयन करने की अनुमति देता है। यह एक ड्रॉप-इन प्रतिस्थापन के रूप में है Hashtable
: ConcurrentMap
इसे लागू करने के अलावा , यह "विरासत" के सभी तरीकों का समर्थन करता है Hashtable
।
प्रत्येक HashMapEntry
एस मूल्य अस्थिर है, जिससे संशोधित संशोधनों और बाद में पढ़ने के लिए ठीक अनाज स्थिरता सुनिश्चित होती है; प्रत्येक पढ़ा सबसे हाल ही में पूरा किया गया अद्यतन दर्शाता है
Iterators और Enumerations विफल सुरक्षित हैं - कुछ बिंदु पर राज्य को दर्शाते हैं जब से पुनरावृत्ति / गणन की रचना; यह एक साथ पढ़ता है और कम स्थिरता की कीमत पर संशोधन के लिए अनुमति देता है। वे ConcurrentModificationException को नहीं फेंकते हैं। हालांकि, पुनरावृत्तियों को एक समय में केवल एक थ्रेड द्वारा उपयोग करने के लिए डिज़ाइन किया गया है।
जैसा Hashtable
लेकिन विपरीत HashMap
, इस वर्ग के रिक्त एक कुंजी या मूल्य के रूप में इस्तेमाल किया जा करने की अनुमति नहीं देता है।
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« नल कीज और नल मान
HashMap
अधिकतम एक अशक्त कुंजी और किसी भी शून्य मान की अनुमति देता है। जहाँ के रूप में Hashtable
एक भी अशक्त कुंजी और अशक्त मूल्य की अनुमति नहीं है, अगर कुंजी या मूल्य अशक्त है तो यह NullPointerException फेंकता है। उदाहरण
« सिंक्रनाइज़, थ्रेड सुरक्षित
Hashtable
आंतरिक रूप से सिंक्रनाइज़ है। इसलिए, Hashtable
बहु थ्रेडेड अनुप्रयोगों में उपयोग करना बहुत सुरक्षित है । जहां HashMap
आंतरिक रूप से सिंक्रनाइज़ नहीं है। इसलिए, HashMap
बाहरी सिंक्रनाइज़ेशन के बिना बहु थ्रेडेड अनुप्रयोगों में उपयोग करना सुरक्षित नहीं है । आप बाह्य रूप से विधि HashMap
का उपयोग करके सिंक्रनाइज़ कर सकते हैं Collections.synchronizedMap()
।
« प्रदर्शन
जैसा Hashtable
कि आंतरिक रूप से सिंक्रनाइज़ किया जाता है, यह Hashtable
तुलना में थोड़ा धीमा बनाता है HashMap
।
@देख
थ्रेडेड ऐप्स के लिए, आप अक्सर समवर्ती हाशिए से दूर हो सकते हैं- आपकी प्रदर्शन आवश्यकताओं पर निर्भर करता है।
1. Hashmap
और HashTable
दोनों दुकान कुंजी और मान।
2. के Hashmap
रूप में एक कुंजी स्टोर कर सकते हैं null
। Hashtable
स्टोर नहीं कर सकते null
।
3. HashMap
सिंक्रनाइज़ नहीं है, लेकिन Hashtable
सिंक्रनाइज़ है।
4. के HashMap
साथ सिंक्रनाइज़ किया जा सकता हैCollection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
पहले से उल्लिखित मतभेदों के अलावा, यह ध्यान दिया जाना चाहिए कि जावा 8 के बाद से, HashMap
ट्रीनेट्स (लाल-काले पेड़) के साथ प्रत्येक बाल्टी में इस्तेमाल किए गए नोड्स (लिंक्ड सूची) को गतिशील रूप से बदल देता है, ताकि भले ही उच्च हैश टकराव मौजूद हो, सबसे खराब जब खोज कर है
HashMap
Vs O (n) के लिए O (लॉग (n) ) इनHashtable
।
* ऊपर उल्लिखित सुधार करने के लिए लागू नहीं किया गया है Hashtable
अभी तक, लेकिन केवल करने के लिए HashMap
, LinkedHashMap
औरConcurrentHashMap
।
वर्तमान में FYI करें,
TREEIFY_THRESHOLD = 8
: यदि एक बाल्टी में 8 से अधिक नोड होते हैं, तो लिंक की गई सूची एक संतुलित पेड़ में बदल जाती है।UNTREEIFY_THRESHOLD = 6
: जब एक बाल्टी बहुत छोटी हो जाती है (हटाने या आकार बदलने के कारण) पेड़ को लिंक की गई सूची में वापस बदल दिया जाता है।हैशटेबल और हैशमैप के साथ 5 बुनियादी अंतर हैं।
मेरा छोटा सा योगदान:
पहले और सबसे महत्वपूर्ण के बीच अलग है
Hashtable
औरHashMap
वह है,HashMap
थ्रेड-सुरक्षित नहीं है जबकिHashtable
एक थ्रेड-सुरक्षित संग्रह है।के बीच दूसरा महत्वपूर्ण अंतर है
Hashtable
औरHashMap
प्रदर्शन, के बादHashMap
से सिंक्रनाइज़ नहीं है यह बेहतर प्रदर्शन करते हैंHashtable
।
Hashtable
बनाम पर तीसरा अंतरHashMap
यह है किHashtable
अप्रचलित वर्ग है और आपको जावा केConcurrentHashMap
स्थान पर उपयोग करना चाहिएHashtable
।
HashMap: यह java.util पैकेज के अंदर उपलब्ध एक वर्ग है और इसका उपयोग कुंजी और मूल्य प्रारूप में तत्व को संग्रहीत करने के लिए किया जाता है।
हैशटेबल: यह एक विरासत वर्ग है जिसे संग्रह ढांचे के अंदर पहचाना जा रहा है।
HashTable jdk में एक विरासत वर्ग है जिसे अब इस्तेमाल नहीं किया जाना चाहिए। के साथ यह प्रयोग बदलें ConcurrentHashMap । आप धागा सुरक्षा, उपयोग की आवश्यकता नहीं है, तो HashMap जो नहीं है threadsafe लेकिन तेजी से और उपयोग करता है कम स्मृति।
Hashtable
जबकि सिंक्रनाइज़ किया गया है HashMap
नहीं है।HashMap
विफल-सुरक्षित है, जबकि एन्यूमरेटर नॉट के लिए Hashtable
। यदि आप पुनरावृत्ति करते समय नक्शा बदलते हैं, तो आपको पता चल जाएगा।HashMap
इसमें शून्य मानों की अनुमति देता है, जबकि Hashtable
ऐसा नहीं है।हैशपॉप और हैशटेबल
1) हैशटेबल और हैशमैप java.util.Map इंटरफ़ेस को लागू करते हैं 2) हैशमैप और हैशटेबल दोनों हैश आधारित संग्रह है। और हैशिंग पर काम कर रहा है। इसलिए ये हाशप और हैशटेबल की समानता है।
1) पहला अंतर है हाशप थ्रेड सुरक्षित नहीं है जबकि हैशटेबल थ्रेडसेफ
2 है) हशप प्रदर्शन बेहतर है क्योंकि यह थ्रेड सुरक्षित नहीं है। जबकि हैशटेबल प्रदर्शन बुद्धिमान बेहतर नहीं है क्योंकि यह थ्रेड सुरक्षित है। एक ही समय में कई थ्रेड हैशटेबल तक नहीं पहुँच सकते हैं।
Hashtable:
हैशटेब एक डेटा संरचना है जो कुंजी-मूल्य जोड़ी के मूल्यों को बरकरार रखती है। यह कुंजी और मान दोनों के लिए अशक्त होने की अनुमति नहीं देता है। NullPointerException
यदि आप शून्य मान जोड़ते हैं, तो आपको मिलेगा । यह सिंक्रनाइज़ है। तो यह अपनी लागत के साथ आता है। केवल एक धागा किसी विशेष समय में हैशटेबल तक पहुंच सकता है ।
उदाहरण :
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
हैश मैप:
HashMap Hashtable की तरह है, लेकिन यह प्रमुख मूल्य जोड़ी को भी स्वीकार करता है। यह कुंजी और मान दोनों के लिए अशक्त होने की अनुमति देता है। इसका प्रदर्शन पहले से बेहतर है HashTable
, क्योंकि यह है unsynchronized
।
उदाहरण:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
HashMap
नकल करते हैं और इसलिए में प्रयोग करने योग्य है GWT client code
, जबकि Hashtable
नहीं है।
पुराने और क्लासिक विषय, इस उपयोगी ब्लॉग को जोड़ना चाहते हैं जो इसे समझाता है:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
मनीष छाबड़ा का ब्लॉग
5 मुख्य अंतर HashMap और हैशटेब को धोखा देते हैं
HashMap और Hashtable दोनों java.util.Map इंटरफ़ेस को लागू करते हैं लेकिन कुछ अंतर हैं जो जावा डेवलपर्स को अधिक कुशल कोड लिखने के लिए समझना चाहिए। जावा 2 प्लेटफॉर्म v1.2 के रूप में, हैशटेबल क्लास को मैप इंटरफेस को लागू करने के लिए रेट्रोफिट किया गया था, जो इसे जावा कलेक्टोरेट फ्रेमवर्क का सदस्य बनाता है।
HashMap और Hashtable के बीच एक प्रमुख अंतर यह है कि HashMap गैर-सिंक्रनाइज़ है, जबकि Hashtable सिंक्रनाइज़ है, जिसका अर्थ है Hashtable धागा-सुरक्षित है और इसे कई थ्रेड के बीच साझा किया जा सकता है, लेकिन HashMap को उचित सिंक्रनाइज़ेशन के बिना कई थ्रेड के बीच साझा नहीं किया जा सकता है। Java 5 ने ConcurrentHashMap पेश किया जो हैशटेबल का एक विकल्प है और जावा में हैशटेबल की तुलना में बेहतर स्केलेबिलिटी प्रदान करता है। सिंक्रोनाइज्ड का मतलब है कि केवल एक धागा एक समय में एक हैश टेबल को संशोधित कर सकता है। मूल रूप से, इसका मतलब है कि हैशटेबल पर अपडेट करने से पहले किसी भी थ्रेड को ऑब्जेक्ट पर लॉक हासिल करना होगा, जबकि अन्य लॉक जारी होने का इंतजार करेंगे।
HashMap वर्ग लगभग Hashtable के बराबर है, सिवाय इसके कि यह नल की अनुमति देता है। (हैशपॅट नल मानों को कुंजी और मूल्य के रूप में अनुमति देता है जबकि हैशटेबल नल की अनुमति नहीं देता है)।
HashMap बनाम Hashtable के बीच तीसरा महत्वपूर्ण अंतर यह है कि HashMap में Iterator एक विफल-तेज़ पुनरावृत्ति है, जबकि Hashtable के लिए एन्यूमरेटर नहीं है और ConcurrentModificationException को फेंकना नहीं है, यदि कोई अन्य थ्रेड किसी भी तत्व को जोड़कर या हटाकर मानचित्र को संशोधित करता है, तो Iterator का स्वयं निकालें ( ) तरीका। लेकिन यह एक गारंटीकृत व्यवहार नहीं है और सबसे अच्छे प्रयास पर जेवीएम द्वारा किया जाएगा। यह जावा में Enumeration और Iterator के बीच एक महत्वपूर्ण अंतर है।
हैशटेबल और हैशपॉब के बीच एक और उल्लेखनीय अंतर यह है कि थ्रेड-सेफ्टी और सिंक्रोनाइज़ेशन के कारण हैशटेबल अगर सिंगल थ्रेडेड वातावरण में उपयोग किया जाता है तो हैशपे की तुलना में बहुत धीमा है। इसलिए यदि आपको सिंक्रनाइज़ेशन की आवश्यकता नहीं है और हैशपॉप केवल एक धागे से उपयोग किया जाता है, तो यह जावा में हैशटेबल का प्रदर्शन करता है।
HashMap गारंटी नहीं देता है कि समय के साथ नक्शे का क्रम स्थिर रहेगा।
ध्यान दें कि HashMap द्वारा सिंक्रनाइज़ किया जा सकता है
Map m = Collections.synchronizedMap(hashMap);
सारांश में, जावा में थ्रेड-सेफ्टी और गति के बीच महत्वपूर्ण अंतर हैं। थ्रेड-सेफ्टी और स्पीड और इसके आधार पर केवल हैशटेबल का उपयोग करें यदि आपको थ्रेड-सेफ्टी की जरूरत है, यदि आप जावा 5 चला रहे हैं, तो जावा में कॉन्ट्रास्ट हाशप का उपयोग करने पर विचार करें।
HashMap और Hashtable दोनों को कुंजी और मूल्य रूप में डेटा स्टोर करने के लिए उपयोग किया जाता है। दोनों अद्वितीय कुंजियों को संग्रहीत करने के लिए हैशिंग तकनीक का उपयोग कर रहे हैं। ash हाशप और हैशटेबल वर्गों के बीच कई अंतर हैं जो नीचे दिए गए हैं।