C # में हैशटेबल पर डिक्शनरी क्यों पसंद की जाती है?


1395

अधिकांश प्रोग्रामिंग भाषाओं में, हैशटैब पर शब्दकोशों को पसंद किया जाता है। उसके पीछे क्या कारण हैं?


21
> यह जरूरी नहीं कि सच हो। एक हैश तालिका एक शब्दकोश का कार्यान्वयन है। उस पर एक विशिष्ट, और यह .NET में डिफ़ॉल्ट एक हो सकता है, लेकिन यह केवल एक परिभाषा के द्वारा नहीं है। मुझे यकीन नहीं है कि यह ईसीएमए मानक द्वारा आवश्यक है, लेकिन एमएसडीएन प्रलेखन बहुत स्पष्ट रूप से इसे हैशटेबल के रूप में कार्यान्वित करने के लिए कहता है। वे भी जब एक विकल्प अधिक उचित है के लिए कई बार SortedList वर्ग प्रदान करते हैं।
Promit

15
@Promit मैंने हमेशा सोचा था कि Dictionaryइसका कार्यान्वयन था Hashtable
b1nary.atr0phy

2
मुझे लगता है कि इसका कारण यह है कि एक शब्दकोश में आप अपने सेल्फी के लिए कुंजी के प्रकार और मूल्य को परिभाषित कर सकते हैं। हैशटेबल केवल ऑब्जेक्ट ले सकता है और हैश के आधार पर जोड़े को बचाता है (ऑब्जेक्ट से। GetHashCode ())।
रेडिएटर

2
@ आपका दावा काफी गलत है ... एक हैश तालिका में केवल प्रत्येक कुंजी का एक उदाहरण होता है, और एक खोज में कई प्रविष्टियों की पैदावार नहीं होती है; यदि आप प्रत्येक कुंजी के साथ कई मानों को जोड़ना चाहते हैं, तो हैश तालिका मानों की सूची बनाएं। "एक शब्दकोश" जैसी कोई डेटा संरचना नहीं है ... शब्दकोश केवल नाम है जो कुछ पुस्तकालय अपनी हैश तालिका के लिए उपयोग करते हैं। उदाहरण के लिए, C # की गैर-सामान्य हैश तालिका को कहा जाता है HashTable। जब उन्होंने भाषा में जेनरिक जोड़ा, तो उन्होंने सामान्य संस्करण को बुलाया Dictionary। दोनों हैश टेबल हैं।
जिम बाल्टर

3
@ आपका दावा गलत है ... एक हैश टेबल ( en.wikipedia.org/wiki/Hash_table ) एक शब्दकोश का एक विशेष कार्यान्वयन है, एक साहचर्य सरणी ( en.wikipedia.org/wiki/Assiveative_array ) और, जा रहा है एक शब्दकोष, केवल प्रत्येक कुंजी का एक उदाहरण होता है, और एक खोज में कई प्रविष्टियां नहीं होती हैं; यदि आप प्रत्येक कुंजी के साथ कई मानों को जोड़ना चाहते हैं, तो हैश तालिका मानों की सूची बनाएं। और .NET शब्दकोश और हैशटेबल कक्षाएं दोनों हैश टेबल हैं।
जिम बाल्टर

जवाबों:


1568

क्या यह की कीमत के लिए, एक शब्दकोश है (धारणात्मक) एक हैश तालिका।

यदि आपका मतलब है "हम Dictionary<TKey, TValue>कक्षा के बजाय कक्षा का उपयोग क्यों करते हैं Hashtable?", तो यह एक आसान जवाब है: Dictionary<TKey, TValue>एक सामान्य प्रकार है, Hashtableहै नहीं। इसका मतलब है कि आपको टाइप सेफ्टी मिलती है Dictionary<TKey, TValue>, क्योंकि आप इसमें कोई रैंडम ऑब्जेक्ट नहीं डाल सकते हैं, और आपको उन वैल्यूज़ को कास्ट करने की ज़रूरत नहीं है जिन्हें आप निकालते हैं।

दिलचस्प बात यह Dictionary<TKey, TValue>है कि .NET फ्रेमवर्क में कार्यान्वयन इस पर आधारित है Hashtable, जैसा कि आप इस टिप्पणी से इसके स्रोत कोड में बता सकते हैं:

जेनेरिक डिक्शनरी को हैशटेबल के स्रोत से कॉपी किया गया था

स्रोत


393
और जेनेरिक संग्रह भी बहुत तेज़ हैं क्योंकि कोई बॉक्सिंग / अनबॉक्सिंग नहीं है
क्रिस एस

6
उपरोक्त कथन के साथ हैशटेबल के बारे में निश्चित नहीं है, लेकिन ArrayList बनाम सूची <t> के लिए यह सच है
क्रिस एस

36
हैशटेब ऑब्जेक्ट का उपयोग आंतरिक रूप से करने के लिए करता है (इसे करने के लिए केवल गैर-सामान्य तरीका), इसलिए इसे बॉक्स / अनबॉक्स भी करना होगा।
ग्वेंटे

16
@ ब्रायनज: एक "हैश टेबल" (दो शब्द) इस तरह की संरचना के लिए कंप्यूटर विज्ञान शब्द है; शब्दकोश एक विशिष्ट कार्यान्वयन है। एक हैशटेबल एक शब्दकोश <ऑब्जेक्ट, ऑब्जेक्ट> (हालांकि थोड़ा अलग इंटरफेस के साथ) से मेल खाता है, लेकिन दोनों हैश टेबल अवधारणा के कार्यान्वयन हैं। और हां, आगे के मामलों को भ्रमित करने के लिए, कुछ भाषाएं अपने हैश टेबल को "डिक्शनरी" (जैसे पायथन) कहते हैं - लेकिन उचित सीएस शब्द अभी भी हैश टेबल है।
माइकल मैडसेन

32
@BrianJ: दोनों HashTable(वर्ग) और Dictionary(वर्ग) हैश टेबल (अवधारणा) हैं, लेकिन एक ए HashTableनहीं है Dictionary, न ही एक Dictionaryहै HashTable। वे बहुत ही समान फैशन में उपयोग किए जाते हैं, और Dictionary<Object,Object>एक ही अनछुए तरीके से कार्य कर सकते हैं जो एक HashTableकरता है, लेकिन वे सीधे किसी भी कोड को साझा नहीं करते हैं (हालांकि भागों को बहुत ही समान तरीके से लागू किए जाने की संभावना है)।
माइकल मैडसेन

625

Dictionary<<< >>> Hashtableअंतर:

  • जेनेरिक <<< >>> गैर-जेनेरिक
  • स्वयं के थ्रेड सिंक्रोनाइज़ेशन की आवश्यकता है <<< >>> विधि के माध्यम से थ्रेड सुरक्षित संस्करण प्रदान करता हैSynchronized()
  • एन्युमरेटेड आइटम: KeyValuePair<<< >>> एनुमेरेटेड आइटम:DictionaryEntry
  • नया (> .NET 2.0 ) <<< >>> पुराना ( .NET 1.0 के बाद से )
  • में है System.Collections.Generic <<< >>> में है System.Collections
  • गैर-मौजूदा कुंजी फेंकता अपवाद के लिए अनुरोध <<< >>> गैर-मौजूदा कुंजी रिटर्न के लिए अनुरोध शून्य
  • मूल्य प्रकारों के लिए संभावित रूप से थोड़ा तेज है <<< >>> थोड़ा धीमा (मूल्य के प्रकारों के लिए बॉक्सिंग / अनबॉक्सिंग) की आवश्यकता है

Dictionary/ Hashtableसमानताएं:

  • दोनों आंतरिक रूप से हैशटैब हैं == कुंजी के अनुसार कई-आइटम डेटा तक तेज़ पहुंच
  • दोनों को अपरिवर्तनीय और अद्वितीय कुंजी चाहिए
  • दोनों की की को अपनी GetHashCode()विधि की जरूरत है

ऐसे ही .NET संग्रह (डिक्शनरी और हैशटेबल के बजाय उपयोग करने वाले उम्मीदवार):

  • ConcurrentDictionary- थ्रेड सेफ (समवर्ती रूप से कई थ्रेड्स से सुरक्षित रूप से एक्सेस किया जा सकता है)
  • HybridDictionary- अनुकूलित प्रदर्शन (कुछ मदों के लिए और कई मदों के लिए भी)
  • OrderedDictionary- मूल्यों को इंटिमेट इंडेक्स के जरिए एक्सेस किया जा सकता है (ऑर्डर में जिसमें आइटम जोड़े गए थे)
  • SortedDictionary- आइटम स्वचालित रूप से सॉर्ट किए गए
  • StringDictionary- जोरदार टाइपिंग और तार के लिए अनुकूलित

11
@ Guillaume86, यही कारण है कि आप msdn.microsoft.com/en-us/library/bb347013.aspx के बजाय TryGetValue का
Trident D'Gao

2
+1 के लिए StringDictionary... जब आप डिफ़ॉल्ट कंस्ट्रक्टर का उपयोग करते हैं तो btw StringDictionaryसमान नहीं Dictionary<string, string>होता है।
चेंग चेन

ParallelExtensionsExtras @ code.msdn.microsoft.com/windowsdesktop/… में एक ऑब्ज़र्वेबल कॉनक्रेक्टर छाया होता है जो महान फ़िरोज़ा के साथ-साथ बाध्यकारी है।
वोट कॉफ़ी

3
बहुत बढ़िया स्पष्टीकरण, यह वास्तव में अच्छा है कि आपने उन सवालों को कम करने के लिए समानताएं सूचीबद्ध कीं जो किसी के दिमाग में आ सकते हैं
mkb


178

क्योंकि Dictionaryएक सामान्य वर्ग ( Dictionary<TKey, TValue>) है, ताकि इसकी सामग्री तक पहुंच टाइप-सुरक्षित है (जैसे कि आपको इससे कास्ट करने की आवश्यकता नहीं है Object, जैसा कि आप के साथ करते हैं Hashtable)।

तुलना

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

सेवा

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

हालांकि, Dictionaryआंतरिक रूप से हैश टेबल के रूप में लागू किया जाता है, इसलिए तकनीकी रूप से यह उसी तरह से काम करता है।


88

FYI करें: .NET में, Hashtableकई रीडर थ्रेड्स और एकल लेखन थ्रेड द्वारा उपयोग के लिए थ्रेड सुरक्षित है, जबकि Dictionaryसार्वजनिक स्थैतिक सदस्यों में थ्रेड सुरक्षित हैं, लेकिन किसी भी उदाहरण के सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है।

हमें Hashtableइस वजह से अपने सभी डिक्शनरों को वापस बदलना पड़ा ।


10
आनंद। डिक्शनरी <T> स्रोत कोड बहुत अधिक क्लीनर और तेज दिखता है। शब्दकोश का उपयोग करना और अपने स्वयं के सिंक्रनाइज़ेशन को लागू करना बेहतर हो सकता है। यदि डिक्शनरी को पढ़ने की आवश्यकता है, तो आपको वर्तमान में डिक्शनरी के पढ़ने / लिखने के तरीकों का उपयोग करना होगा। यह बहुत लॉकिंग होगा, लेकिन यह सही होगा।
त्रिनको

10
वैकल्पिक रूप से, यदि आपके रीड को बिल्कुल चालू नहीं होना है, तो आप शब्दकोश को अपरिवर्तनीय मान सकते हैं। तब आप डिक्शनरी का संदर्भ ले सकते हैं और रीड को सिंक्रोनाइज़ न करके प्रदर्शन हासिल कर सकते हैं (क्योंकि यह अपरिवर्तनीय और स्वाभाविक रूप से थ्रेड-सेफ़ है)। इसे अपडेट करने के लिए, आप बैकग्राउंड में डिक्शनरी की एक पूरी अपडेटेड कॉपी का निर्माण करते हैं, फिर इंटरलॉक के साथ संदर्भ को स्वैप करें ।CompareExchange (एक ही राइटिंग थ्रेड मानकर; कई राइटिंग थ्रेड्स को अपडेट को सिंक्रनाइज़ करने की आवश्यकता होगी)।
त्रिकोको

38
.Net 4.0 ने वह ConcurrentDictionaryवर्ग जोड़ा जिसमें थ्रेड-सुरक्षित होने के लिए सभी सार्वजनिक / संरक्षित तरीके लागू हैं। यदि आपको विरासत प्लेटफार्मों का समर्थन करने की आवश्यकता नहीं है, तो यह आपको Hashtableमल्टीथ्रेड कोड में प्रतिस्थापित करने देगा
Dan

बचाव के लिए अनाम। अच्छा जवाब।
अनकुलुंकुलु

5
मुझे यह पढ़कर याद आया कि हैशटेबल केवल उस परिदृश्य में पाठक-लेखक थ्रेड-सेफ़ है, जहाँ सूचनाओं को टेबल से कभी डिलीट नहीं किया जाता है। यदि एक पाठक एक आइटम के लिए पूछ रहा है जो तालिका में है, जबकि एक अलग आइटम को हटाया जा रहा है, और पाठक को आइटम के लिए एक से अधिक स्थानों पर देखना होगा, तो यह संभव है कि जब पाठक लेखक को खोज रहा है तो वह आइटम को स्थानांतरित कर सकता है ऐसी जगह से जिसकी जांच नहीं की गई है, जिसके परिणामस्वरूप झूठी रिपोर्ट है कि आइटम मौजूद नहीं है।
23

68

.NET में, मुख्य रूप से Dictionary<,>और अंतर HashTableयह है कि पूर्व एक सामान्य प्रकार है, इसलिए आपको स्थैतिक प्रकार की जाँच के संदर्भ में जेनरिक के सभी लाभ मिलते हैं (और मुक्केबाजी को कम किया जाता है, लेकिन यह उतना बड़ा नहीं है जितना लोग सोचते हैं। प्रदर्शन की शर्तें - मुक्केबाजी के लिए एक निश्चित स्मृति लागत है, हालांकि)।


34

लोग कह रहे हैं कि एक शब्दकोश हैश तालिका के समान है।

आवश्यक रूप से यह सही नहीं है। शब्दकोश को लागू करने का एक तरीका हैश तालिका है । उस पर एक विशिष्ट एक, और यह Dictionaryवर्ग में .NET में डिफ़ॉल्ट एक हो सकता है , लेकिन यह केवल एक परिभाषा के द्वारा नहीं है।

आप किसी लिंक किए गए सूची या खोज ट्री का उपयोग करके समान रूप से अच्छी तरह से एक शब्दकोश को लागू कर सकते हैं, यह सिर्फ उतना ही कुशल नहीं होगा (कुशल के कुछ मीट्रिक के लिए)।


4
एमएस डॉक्स का कहना है: "ओ (1) के करीब, इसकी कुंजी का उपयोग करके किसी मूल्य को पुनः प्राप्त करना, क्योंकि डिक्शनरी <(TKI, TValue>)>) वर्ग को हैश टेबल के रूप में लागू किया जाता है।" - इसलिए आपको डील करते समय हैशटेबल की गारंटी देनी चाहिए Dictionary<K,V>IDictionary<K,V>कुछ भी हो सकता है, हालांकि :)
स्निपार्क

13
@ rix0rrr - मुझे लगता है कि आपको लगता है कि पीछे की ओर, एक शब्दकोश एक हैशटेबल का उपयोग करता है न कि हैशटेबल एक शब्दकोश का उपयोग करता है।
जोसेफ हैमिल्टन

8
@JosephHamilton - rix0rrr यह अधिकार मिल गया है: "एक हैश तालिका है एक के एक कार्यान्वयन शब्दकोश ।" उनका मतलब अवधारणा "शब्दकोश" है, न कि वर्ग (निचले मामले पर ध्यान दें)। वैचारिक रूप से, एक हैश तालिका एक शब्दकोश इंटरफ़ेस लागू करता है। .NET में, शब्दकोश IDEDIA को लागू करने के लिए एक हैश तालिका का उपयोग करता है। यह गड़बड़ है;)
रॉबर्ट हेंसिंग

मैं .NET के बारे में बात कर रहा था, क्योंकि वह अपनी प्रतिक्रिया में संदर्भित है।
जोसेफ हैमिल्टन

2
@JosephHamilton: औजार (या के कार्यान्वयन ) भी दूर के रूप में एक ही बात मतलब यह नहीं है का उपयोग करता है । काफी विपरीत। शायद यह स्पष्ट हो जाता अगर वह इसे थोड़ा अलग तरीके से कहता (लेकिन उसी अर्थ के साथ): "एक हैश तालिका एक शब्दकोश को लागू करने का एक तरीका है"। यही है, यदि आप एक शब्दकोश की कार्यक्षमता चाहते हैं, तो ऐसा करने का एक तरीका ( शब्दकोश को लागू करना) हैशटेबल का उपयोग करना है।
टूलमेकरसेव

21

Collections& Genericsवस्तुओं के समूह को संभालने के लिए उपयोगी हैं। .NET में, सभी संग्रह ऑब्जेक्ट इंटरफ़ेस के अंतर्गत आते हैं IEnumerable, जो बदले में ArrayList(Index-Value))& है HashTable(Key-Value)। .NET फ्रेमवर्क 2.0 के बाद, ArrayListऔर HashTableसाथ बदल दिया गया Listऔर Dictionary। अब, Arraylistऔर HashTableकोई और अधिक आजकल परियोजनाओं में उपयोग किया जाता है।

के बीच अंतर करने के लिए आ रहा है HashTableऔर Dictionary, Dictionaryजहां के रूप में सामान्य है Hastableजेनेरिक नहीं है। हम किसी भी प्रकार की वस्तु को जोड़ सकते हैं HashTable, लेकिन पुनर्प्राप्त करते समय हमें इसे आवश्यक प्रकार में डालना होगा। इसलिए, यह सुरक्षित नहीं है। लेकिन dictionary, खुद को घोषित करते समय हम कुंजी और मूल्य के प्रकार को निर्दिष्ट कर सकते हैं, इसलिए पुन: प्राप्त करते समय कास्ट करने की कोई आवश्यकता नहीं है।

आइए एक उदाहरण देखें:

हैश टेबल

class HashTableProgram
{
    static void Main(string[] args)
    {
        Hashtable ht = new Hashtable();
        ht.Add(1, "One");
        ht.Add(2, "Two");
        ht.Add(3, "Three");
        foreach (DictionaryEntry de in ht)
        {
            int Key = (int)de.Key; //Casting
            string value = de.Value.ToString(); //Casting
            Console.WriteLine(Key + " " + value);
        }

    }
}

शब्दकोश,

class DictionaryProgram
{
    static void Main(string[] args)
    {
        Dictionary<int, string> dt = new Dictionary<int, string>();
        dt.Add(1, "One");
        dt.Add(2, "Two");
        dt.Add(3, "Three");
        foreach (KeyValuePair<int, String> kv in dt)
        {
            Console.WriteLine(kv.Key + " " + kv.Value);
        }
    }
}

2
KeyValuePair के लिए डेटाटाइप को स्पष्ट रूप से निर्दिष्ट करने के बजाय, हम var का उपयोग कर सकते हैं। तो, इससे टाइपिंग कम होगी - foreach (dt में var kv) ... सिर्फ एक सुझाव।
रॉन

16

शब्दकोश:

  • यदि हम एक ऐसी कुंजी खोजने की कोशिश करते हैं जो मौजूद नहीं है, तो यह रिटर्न / फेंकता है।

  • यह एक हैशटेबल से तेज है क्योंकि इसमें बॉक्सिंग और अनबॉक्सिंग नहीं है।

  • केवल सार्वजनिक स्थिर सदस्य ही थ्रेड सुरक्षित हैं।

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

    उदाहरण: Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();

  • Dictionay हैशटेबल का एक प्रकार-सुरक्षित कार्यान्वयन है, Keysऔर Valuesदृढ़ता से टाइप किया जाता है।

हैश टेबल:

  • यदि हम एक कुंजी खोजने की कोशिश करते हैं जो मौजूद नहीं है, तो यह अशक्त हो जाता है।

  • यह शब्दकोश की तुलना में धीमा है क्योंकि इसमें बॉक्सिंग और अनबॉक्सिंग की आवश्यकता होती है।

  • हैशटेबल में सभी सदस्य सुरक्षित हैं,

  • हैशटेबल एक सामान्य प्रकार नहीं है,

  • हैशटेबल शिथिल टाइप डेटा संरचना है, हम किसी भी प्रकार की कुंजी और मान जोड़ सकते हैं।


यदि हम एक कुंजी खोजने की कोशिश करते हैं, तो यह अपवाद देता है। यदि आप उपयोग नहीं करते हैंDictionary.TryGetValue
जिम बाल्टर

16

MSDN पर C # लेख का उपयोग करके डेटा संरचनाओं की व्यापक परीक्षा बताती है कि टक्कर रिज़ॉल्यूशन रणनीति में भी अंतर है :

हैशटेबल वर्ग एक तकनीक का उपयोग करता है जिसे रिहाशिंग कहा जाता है ।

रिहाशिंग निम्नानुसार काम करता है: हैश विभिन्न कार्यों का एक समूह है, एच 1 ... एच एन , और जब हैश तालिका से किसी आइटम को सम्मिलित करना या पुनर्प्राप्त करना शुरू में एच 1 हैश फ़ंक्शन का उपयोग किया जाता है। यदि यह टकराव की ओर जाता है, तो इसके बजाय H 2 की कोशिश की जाती है, और जरूरत पड़ने पर H n तक की तरफ।

डिक्शनरी एक ऐसी तकनीक का उपयोग करती है जिसे जंजीर कहा जाता है ।

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


16

.NET फ्रेमवर्क 3.5 के बाद से एक ऐसा भी है HashSet<T>जो Dictionary<TKey, TValue>आपको केवल कुंजी और कोई मान की आवश्यकता के सभी पेशेवरों को प्रदान करता है ।

इसलिए यदि आप एक का उपयोग करते हैं Dictionary<MyType, object>और हमेशा nullउस प्रकार की सुरक्षित हैश तालिका का अनुकरण करने के लिए मूल्य निर्धारित करते हैं जिसे आपको शायद स्विच करने पर विचार करना चाहिए HashSet<T>


14

Hashtableताकि आप को किसी भी प्रकार की कुंजी और मूल्यों को जोड़ सकते हैं, एक शिथिल टाइप डेटा संरचना है HashtableDictionaryवर्ग एक प्रकार-सुरक्षित है Hashtableकार्यान्वयन, और कुंजी और मूल्यों दृढ़ता से लिखे जाते हैं। एक Dictionaryउदाहरण बनाते समय , आपको कुंजी और मान दोनों के लिए डेटा प्रकार निर्दिष्ट करना होगा।


11

ध्यान दें कि MSDN कहता है: "शब्दकोश <(का <(TKey, TValue>)>) वर्ग को हैश टेबल के रूप में लागू किया जाता है ", "शब्दकोश <(<(TKey, TValue>)>) वर्ग को हैशटेबल के रूप में लागू किया जाता है "

शब्दकोश को हैशटेबल के रूप में लागू नहीं किया गया है, लेकिन इसे हैश टेबल की अवधारणा के बाद लागू किया गया है। जेनरेशन के उपयोग के कारण हैशटेबल वर्ग के लिए कार्यान्वयन असंबंधित है, हालांकि आंतरिक रूप से माइक्रोसॉफ्ट एक ही कोड का उपयोग कर सकता था और प्रकार ऑब्जेक्ट के प्रतीकों को TKey और TValue के साथ बदल सकता था।

.NET 1.0 में जेनरिक मौजूद नहीं था; यह वह जगह है, जहां हैशटेबल और एरियर लेलिस्ट मूल रूप से शुरू हुआ था।


क्या आप उस MSDN उद्धरण को ठीक कर सकते हैं? कुछ याद आ रहा है या गलत है; यह व्याकरणिक नहीं है और कुछ हद तक समझ से बाहर है।
पीटर मॉर्टेंसन

10

हैश टेबल:

कुंजी / मान को एक वस्तु (बॉक्सिंग) प्रकार में परिवर्तित किया जाएगा जबकि ढेर में संग्रहीत किया जाएगा।

कुंजी / मान को ढेर से पढ़ते समय वांछित प्रकार में बदलने की आवश्यकता है।

ये ऑपरेशन बहुत महंगे हैं। हमें यथासंभव मुक्केबाजी / अनबॉक्सिंग से बचने की आवश्यकता है।

शब्दकोश: हैशटेबल का सामान्य संस्करण।

कोई बॉक्सिंग / अनबॉक्सिंग नहीं। कोई रूपांतरण आवश्यक नहीं है।


8

हैशटेबल ऑब्जेक्ट में बाल्टी होती है जिसमें संग्रह के तत्व होते हैं। बाल्टी हैशटेबल के भीतर तत्वों का एक आभासी उपसमूह है, जो अधिकांश संग्रहों की तुलना में आसान और तेज़ी से खोज और पुनर्प्राप्ति करता है

शब्दकोश वर्ग में हैशटेबल वर्ग के समान कार्यक्षमता है। एक विशिष्ट प्रकार के एक शब्दकोश (ऑब्जेक्ट के अलावा) में मूल्य प्रकारों के लिए एक हैशटेबल की तुलना में बेहतर प्रदर्शन होता है क्योंकि हैशटेबल के तत्व ऑब्जेक्ट प्रकार के होते हैं और इसलिए, बॉक्सिंग और अनबॉक्सिंग आमतौर पर तब होते हैं जब एक मूल्य प्रकार को संग्रहीत या पुनर्प्राप्त किया जाता है।

आगे पढ़ने के लिए: हैशटेबल और डिक्शनरी कलेक्शन के प्रकार


7

एक और महत्वपूर्ण अंतर यह है कि हैशटेबल धागा सुरक्षित है। हैशटेबल में अंतर्निहित कई पाठक / एकल लेखक (एमआर / एसडब्ल्यू) थ्रेड सुरक्षा है, जिसका अर्थ है कि हैशटेबल एक लेखक को कई पाठकों के साथ बिना लॉक किए अनुमति देता है।

शब्दकोश के मामले में कोई धागा सुरक्षा नहीं है; यदि आपको थ्रेड सुरक्षा की आवश्यकता है, तो आपको अपने स्वयं के सिंक्रनाइज़ेशन को लागू करना होगा।

आगे विस्तृत करने के लिए:

हैशटेबल Synchronizedसंपत्ति के माध्यम से कुछ थ्रेड-सुरक्षा प्रदान करता है , जो संग्रह के चारों ओर एक थ्रेड-सुरक्षित आवरण देता है। रैपर हर ऐड पर पूरे कलेक्शन को लॉक करके या ऑपरेशन को हटाकर काम करता है। इसलिए, संग्रह को एक्सेस करने का प्रयास करने वाले प्रत्येक थ्रेड को एक लॉक लेने के लिए अपनी बारी का इंतजार करना होगा। यह स्केलेबल नहीं है और बड़े संग्रह के लिए महत्वपूर्ण प्रदर्शन गिरावट का कारण बन सकता है। इसके अलावा, डिजाइन पूरी तरह से दौड़ की स्थिति से सुरक्षित नहीं है।

.NET फ्रेमवर्क 2.0 संग्रह कक्षाएं जैसे List<T>, Dictionary<TKey, TValue>, आदि किसी भी थ्रेड सिंक्रनाइज़ेशन प्रदान नहीं करते हैं; जब आइटम जोड़े जाते हैं या समवर्ती रूप से कई थ्रेड पर निकाले जाते हैं, तो उपयोगकर्ता कोड को सभी सिंक्रनाइज़ेशन प्रदान करना होगा

यदि आपको टाइप सुरक्षा के साथ-साथ थ्रेड सुरक्षा की आवश्यकता है, तो .NET फ्रेमवर्क में समवर्ती संग्रह कक्षाओं का उपयोग करें। आगे यहां पढ़ रहे हैं

एक अतिरिक्त अंतर यह है कि जब हम शब्दकोश में कई प्रविष्टियाँ जोड़ते हैं, तो जिस क्रम में प्रविष्टियाँ जोड़ी जाती हैं उसका क्रम बना रहता है। जब हम शब्दकोश से आइटम पुनः प्राप्त करते हैं तो हमें उसी क्रम में रिकॉर्ड मिलेंगे, जिसे हमने उन्हें सम्मिलित किया है। जबकि हैशटेब सम्मिलन आदेश को संरक्षित नहीं करता है।


जो मैं समझता हूं, वह Hashsetउपयोग परिदृश्यों में MR / SW थ्रेड सुरक्षा की गारंटी देता है जिसमें विलोपन शामिल नहीं है । मुझे लगता है कि यह पूरी तरह से एमआर / एसडब्ल्यू सुरक्षित होने का इरादा किया गया है, लेकिन सुरक्षित रूप से हटाने से एमआर / एसडब्ल्यू सुरक्षा का खर्च बढ़ जाता है। जबकि Dictionaryनो-डिलीट परिदृश्यों में न्यूनतम लागत पर MR / SW सुरक्षा प्रदान कर सकता था, मुझे लगता है कि MS नो-डिलीट परिदृश्यों को "विशेष" मानने से बचना चाहता था।
सुपरकैट

5

एक और अंतर जो मैं समझ सकता हूं वह है:

हम वेब सेवाओं के साथ शब्दकोश <केटी, वीटी> (जेनरिक) का उपयोग नहीं कर सकते हैं। कारण कोई वेब सेवा मानक नहीं है जेनरिक मानक का समर्थन करता है।


हम साबुन आधारित वेब सेवा में सामान्य सूचियों (सूची <string>) का उपयोग कर सकते हैं। लेकिन, हम डिक्शनरी (या हैशटेबल) का उपयोग वेबसेवा में नहीं कर सकते हैं। मुझे लगता है कि इसका कारण यह है कि .net xmlserializer डिक्शनरी ऑब्जेक्ट को हैंडल नहीं कर सकता है।
सिद्धार्थ

5

Dictionary<> एक सामान्य प्रकार है और इसलिए यह सुरक्षित है।

आप हैशटेबल में किसी भी मूल्य प्रकार को सम्मिलित कर सकते हैं और यह कभी-कभी अपवाद फेंक सकता है। लेकिन Dictionary<int>केवल पूर्णांक मानों Dictionary<string>को स्वीकार करेंगे और इसी तरह केवल तार को स्वीकार करेंगे।

इसलिए, इसके Dictionary<>बजाय इसका उपयोग करना बेहतर है HashTable


0

अधिकांश प्रोग्रामिंग भाषाओं में, हैशटैब पर शब्दकोशों को पसंद किया जाता है

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

C # में, हालांकि, स्पष्ट कारण (मेरे लिए) यह है कि C # HashTables और System.Collections के अन्य सदस्य बड़े पैमाने पर अप्रचलित हैं। वे c # V1.1 में मौजूद थे। उन्हें System.Collections.Generic नाम स्थान में सामान्य कक्षाओं द्वारा C # 2.0 से बदल दिया गया है।


एक शब्दकोश पर हैशटेबल के फायदों में से एक यह है कि अगर एक कुंजी एक शब्दकोश में मौजूद नहीं है, तो यह एक त्रुटि फेंक देगा। यदि हैशटेबल में कोई कुंजी मौजूद नहीं है, तो यह रिक्त हो जाता है।
बिल नॉर्मन

C # में मैं अभी भी System.Collections.Hashtable का उपयोग करने से बचूंगा क्योंकि उनके पास जेनरिक का लाभ नहीं है। यदि आपको पता नहीं होगा कि कुंजी मौजूद है, तो आप डिक्शनरी के ट्रायगेटवैल्यू या हैस्के का उपयोग कर सकते हैं।
क्रिस्तिपांप

हूप्स, हस्के नहीं, यह कॉन्टेन्सकेई होना चाहिए।
kristianp

-3

.NET रिफ्लेक्टर का उपयोग करके मैं जो देखता हूं, उसके अनुसार :

[Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
    // Fields
    private Hashtable hashtable;

    // Methods
    protected DictionaryBase();
    public void Clear();
.
.
.
}
Take note of these lines
// Fields
private Hashtable hashtable;

तो हम यह सुनिश्चित कर सकते हैं कि DictionaryBase एक HashTable का आंतरिक रूप से उपयोग करता है।


16
System.Collections.Generic.Dictionary <TKey, TValue> DictionaryBase से प्राप्त नहीं होता है।
स्नोमार्क

"तो हम यह सुनिश्चित कर सकते हैं कि DictionaryBase एक HashTable का आंतरिक रूप से उपयोग करता है।" - यह अच्छा है, लेकिन इसका सवाल से कोई लेना-देना नहीं है।
जिम बाल्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.