HashMap बनाम Hashtable Java में: अंतर और आंतरिक संरचना

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Java में HashMap बनाम Hashtable: कौन किससे बेहतर? अंदरूनी कार्यप्रणाली को समझें

\n\n

यदि आपने कभी सोचा है: "आखिर HashMap और Hashtable में क्या अंतर है?" — तो आप अकेले नहीं हैं। यह Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है, और यह उचित भी है। दोनों क्लास "कुंजी — मान" प्रारूप में डेटा संग्रहीत करते हैं, दोनों हैशिंग का उपयोग करते हैं, लेकिन फिर भी अलग-अलग दुनिया में रहते हैं। एक तेज़ और आधुनिक है, दूसरा पुराना, विश्वसनीय, लेकिन थोड़ा धीमा। आइए उनके "अंदरूनी हिस्से" में झाँकें और समझें कि क्या क्या है।

\n\n

इस लेख में हम केवल अंतरों को सूचीबद्ध नहीं करेंगे। हम समझेंगे कि आंतरिक तंत्र कैसे काम करता है, क्यों एक क्लास null की अनुमति देता है और दूसरा नहीं, और कब दोनों के बजाय ConcurrentHashMap का उपयोग करना चाहिए।

\n\n

इतिहास में एक संक्षिप्त भ्रमण

\n\n

Hashtable Java में संस्करण 1.0 में ही आ गया था। यह पहले कलेक्शन क्लासेस में से एक था, और शुरू से ही सिंक्रोनाइज़्ड था। उस समय मल्टीथ्रेडिंग दुर्लभ थी, लेकिन Java डेवलपर्स ने सुरक्षा के लिए ऐसा किया। बाद में, Java 2 (1.2) में, Collections Framework से नए कलेक्शन आए, और उनमें से एक HashMap था। यह असिंक्रोनाइज़्ड था, लेकिन बहुत तेज़ था। तब से Hashtable को पुराना (legacy) माना जाता है, हालाँकि इसे भाषा से हटाया नहीं गया है।

\n\n

मुख्य अंतर: सिंक्रोनाइज़ेशन और थ्रेड्स

\n\n

पहला और सबसे महत्वपूर्ण अंतर सिंक्रोनाइज़ेशन है। Hashtable के तरीके (जैसे put(), get(), remove()) synchronized कीवर्ड से चिह्नित हैं। इसका मतलब है कि दो थ्रेड एक ही Hashtable ऑब्जेक्ट पर एक ही विधि को एक साथ निष्पादित नहीं कर सकते। यह एक लाभ की तरह लगता है, लेकिन व्यवहार में यह एक अड़चन बन जाता है।

\n\n
// Hashtable — सभी विधियाँ सिंक्रोनाइज़्ड हैं\nHashtable<String, String> table = new Hashtable<>();\ntable.put("key1", "value1"); // थ्रेड-सुरक्षित, लेकिन उच्च प्रतिस्पर्धा में धीमा\n\n// HashMap — सिंक्रोनाइज़्ड नहीं है\nHashMap<String, String> map = new HashMap<>();\nmap.put("key1", "value1"); // तेज़, लेकिन थ्रेड-सुरक्षित नहीं\n
\n\n

यदि आप सिंगल-थ्रेडेड एप्लिकेशन (जो कि अधिकांश हैं) में काम कर रहे हैं, तो HashMap तेज़ी से काम करेगा क्योंकि उसे लॉक प्राप्त करने और छोड़ने में समय बर्बाद नहीं करना पड़ता। यदि आपको थ्रेड-सुरक्षा की आवश्यकता है, तो Hashtable का उपयोग न करें, बल्कि ConcurrentHashMap (Java 5 में आया) का उपयोग करें। यह अधिक सूक्ष्म लॉकिंग (सेगमेंट या बकेट-स्तरीय लॉक) का उपयोग करता है और मल्टीथ्रेडेड वातावरण में काफी तेज़ी से काम करता है।

\n\n

Null, null और फिर null

\n\n

दूसरा महत्वपूर्ण अंतर null के साथ काम करना है। HashMap null को कुंजी (केवल एक बार) और मान (जितनी बार चाहें) दोनों के रूप में उपयोग करने की अनुमति देता है। Hashtable, यदि आप null पास करने का प्रयास करते हैं, तो NullPointerException फेंक देगा।

\n\n
HashMap<String, String> map = new HashMap<>();\nmap.put(null, "nullKey"); // OK\nmap.put("key", null);     // OK\nSystem.out.println(map.get(null)); // "nullKey"\n\nHashtable<String, String> table = new Hashtable<>();\n// table.put(null, "value"); // NullPointerException!\n// table.put("key", null);   // NullPointerException!\n
\n\n

ऐसा क्यों है? इसका कारण हैशिंग का काम करने का तरीका है। HashMap में, null कुंजी के लिए एक विशेष हैश-कोड 0 का उपयोग किया जाता है, और इसे शून्य बकेट में रखा जाता है। Hashtable एक पुराने तंत्र का उपयोग करता है, जहाँ null पर hashCode() कॉल करने से त्रुटि होती है। इसके अलावा, Hashtable null-मानों के लिए डिज़ाइन नहीं किया गया है, क्योंकि यह सिंक्रोनाइज़्ड संचालन के तर्क को तोड़ देगा।

\n\n

आंतरिक संरचना: हैश-टेबल अंदरूनी रूप से कैसे काम करती है

\n\n

अंतर को और गहराई से समझने के लिए, आइए अंदर झाँकें। HashMap और Hashtable दोनों हैश-टेबल पर आधारित हैं। यह "बकेट" की एक सरणी है, जहाँ प्रत्येक बकेट एक लिंक्ड लिस्ट (या Java 8 से शुरू होकर एक ट्री) है। जब आप

ब्लॉग

पुस्तक अनुशंसाएँ