HashSet <T> और List <T> में क्या अंतर है?


156

आप के बीच अंतर क्या है व्याख्या कर सकते हैं HashSet<T>और List<T>नेट में?

हो सकता है कि आप एक उदाहरण के साथ समझा सकें कि किन मामलों में HashSet<T>पसंद किया जाना चाहिए List<T>?



मेरा सुझाव है कि आप विकिपीडिया लेख en.wikipedia.org/wiki/Hash_table और en.wikipedia.org/wiki/Dynamic_array पर सलाह लें ।
20

प्रदर्शन से संबंधित के लिए, हैशसेट-बनाम-लिस्ट-प्रदर्शन
nawfal

जवाबों:


213

एक सूची के विपरीत <> ...

  1. A HashSet एक सूची है जिसमें कोई भी डुप्लिकेट सदस्य नहीं है।

  2. क्योंकि एक हैशसेट में केवल अद्वितीय प्रविष्टियाँ होने के लिए बाध्य है, आंतरिक संरचना को खोजने के लिए अनुकूलित किया गया है (सूची के साथ तुलना में) - यह काफी तेज है

  3. यदि पहले से सेट में मौजूद होने के कारण इसके अलावा विफल रहता है, तो हैशसेट में जोड़ना एक बूलियन रिटर्न देता है

  4. एक सेट के खिलाफ गणितीय सेट ऑपरेशन कर सकते हैं: संघ / अंतर्ग्रहण / IsSubsetOf आदि।

  5. HashSet IList को केवल ICollection लागू नहीं करता है

  6. आप HashSet के साथ सूचकांकों का उपयोग नहीं कर सकते, केवल एन्यूमरेटर्स।

यदि आप सेट संचालन करने में रुचि रखते हैं, तो हैशसेट का उपयोग करने का मुख्य कारण होगा।

2 सेट दिए गए: hashSet1 और hashSet2

 //returns a list of distinct items in both sets
 HashSet set3 = set1.Union( set2 );

LINQ का उपयोग करके समतुल्य ऑपरेशन के साथ तुलना में उड़ता है। यह भी लिखने के लिए neater है!


आईडीके, मुझे Unionविधि के साथ समस्या थी । मैंने UnionWithइसके बजाय इस्तेमाल किया था ।
उपयोगकर्ता

2
+1 के लिए "HashedSet का उपयोग करने का मुख्य कारण यह होगा कि क्या आप सेट संचालन करने में रुचि रखते हैं।"
LCJ

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

अच्छा उत्तर। मुझे कुछ प्रदर्शन विशेषता अंतर जोड़ने के लिए भी लुभाया जाता है।
नवफाल

1
प्रश्न: मुख्य कारण डुप्लिकेट आइटम नहीं होने की निश्चितता है?
एंड्रिया स्कारफोनी

54

अधिक सटीक होने के लिए उदाहरणों के साथ प्रदर्शित करने देता है,

आप निम्न उदाहरण में हैशसेट का उपयोग नहीं कर सकते हैं।

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
    Console.WriteLine(hashSet1[i]);

hashSet1[i] कोई त्रुटि उत्पन्न करेगा:

'System.Collections.Generic.HashSet' प्रकार की अभिव्यक्ति के साथ अनुक्रमण लागू नहीं कर सकता

आप फॉर्च स्टेटमेंट का उपयोग कर सकते हैं:

foreach (var item in hashSet1)
    Console.WriteLine(item);

आप डुप्लीकेट आइटम को हैशसेट में नहीं जोड़ सकते हैं जबकि सूची आपको ऐसा करने की अनुमति देती है और जब आप हाशसेट में कोई आइटम जोड़ रहे हैं, तो आप व्हीटर की जांच कर सकते हैं कि उसमें आइटम है या नहीं।

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
if (hashSet1.Add("1"))
   Console.WriteLine("'1' is successfully added to hashSet1!");
else
   Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");

HashSet जैसे कुछ उपयोगी कार्य करता है IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, SymmetricExceptWithआदि

IsProperSubsetOf:

HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
HashSet<string> hashSet3 = new HashSet<string>() { "1", "2", "3", "4", "5" };
if (hashSet1.IsProperSubsetOf(hashSet3))
    Console.WriteLine("hashSet3 contains all elements of hashSet1.");
if (!hashSet1.IsProperSubsetOf(hashSet2))
    Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");

UnionWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8

IntersectWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" }
hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8

ExceptWith :

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6

SymmetricExceptWith :

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6

वैसे, हैशसेट में ऑर्डर संरक्षित नहीं है। उदाहरण में, हमने अंतिम "तत्व" को जोड़ा है लेकिन यह दूसरे क्रम में है:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
hashSet1.Add("1");    // 3, 4, 8, 1
hashSet1.Remove("4"); // 3, 8, 1
hashSet1.Add("2");    // 3, 2 ,8, 1

51

A HashSet<T>एक वर्ग है जिसे आपको O(1)रोकथाम के लिए देखने के लिए डिज़ाइन किया गया है (यानी, इस संग्रह में एक विशेष ऑब्जेक्ट है, और मुझे उत्तर को तेज़ी से बताएं)।

A एक List<T>ऐसा वर्ग है जो आपको O(1)गतिशील पहुंच के साथ एक संग्रह देने के लिए डिज़ाइन किया गया है जो गतिशील रूप से बढ़ सकता है (गतिशील सरणी सोचें)। आप O(n)समय में रोकथाम का परीक्षण कर सकते हैं (जब तक कि सूची को क्रमबद्ध नहीं किया जाता है, तब आप O(log n)समय में एक द्विआधारी खोज कर सकते हैं )।

हो सकता है कि आप एक उदाहरण के साथ समझा सकें कि किन मामलों में के HashSet<T>खिलाफ प्राथमिकता दी जानी चाहिएList<T>

जब आप में नियंत्रण का परीक्षण करना चाहते हैं O(1)


यदि सूची क्रमबद्ध है, तो इसे छोड़कर O (लॉग एन); आखिरकार, यह एक अनसुलझी सूची में देखने की तुलना में तेज़ है।
आंद्रेई

20

List<T>जब आप चाहते हैं तो उपयोग करें :

  • एक निश्चित क्रम में वस्तुओं के संग्रह को स्टोर करें।

यदि आप उस वस्तु का सूचकांक जानते हैं जो आप चाहते हैं (वस्तु के मूल्य के बजाय) पुनर्प्राप्ति है O(1)। यदि आप इंडेक्स को नहीं जानते हैं, तो आइटम को खोजने में अधिक समय लगता है, O(n)एक अनसुचित संग्रह के लिए।

Hashset<T>जब आप चाहते हैं तो उपयोग करें :

  • अगर किसी संग्रह में एक निश्चित वस्तु समाहित है तो जल्दी से पता करें।

यदि आप उस चीज़ का नाम जानते हैं जिसे आप ढूंढना चाहते हैं, तो लुकअप O(1)(वह 'हैश' भाग है)। यह करता है की तरह एक आदेश को बनाए रखने List<T>और आप डुप्लिकेट स्टोर नहीं कर सकते (एक डुप्लिकेट को जोड़ने का कोई प्रभाव नहीं है, यह 'सेट' हिस्सा है)।

जब Hashset<T>आप स्क्रैबल के खेल में खेला जाने वाला शब्द अंग्रेजी (या अन्य भाषा) में मान्य शब्द है, तो आप इसका उपयोग करना चाहते हैं, तो इसका एक उदाहरण होगा। इससे भी बेहतर होगा कि आप इस तरह के गेम के ऑनलाइन संस्करण के सभी उदाहरणों द्वारा उपयोग की जाने वाली वेब सेवा का निर्माण करना चाहते हों।

एक List<T>खिलाड़ी स्कोर ट्रैक करने के लिए स्कोरबोर्ड बनाने के लिए एक अच्छा डेटा संरचना होगा।


15

सूची एक आदेशित सूची है। यह है

  • एक पूर्णांक सूचकांक द्वारा पहुँचा
  • डुप्लिकेट हो सकते हैं
  • एक पूर्वानुमेय आदेश है

हैशसेट एक सेट है। यह:

  • डुप्लिकेट आइटम ब्लॉक कर सकते हैं ( Add (T) देखें )
  • सेट के भीतर वस्तुओं के ऑर्डर की गारंटी नहीं देता है
  • संचालन है जो आप एक सेट पर उम्मीद करेंगे, जैसे , IntersectWith, IsProperSubsetOf, UnionWith।

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


3

जरूरी नहीं कि सूची अद्वितीय हो, जबकि हैशसेट एक के लिए है।


3

एक सूची टाइप टी की वस्तुओं का एक ऑर्डर किया गया संग्रह है जो एक सरणी के विपरीत आप प्रविष्टियों को जोड़ और हटा सकते हैं।

आप एक सूची का उपयोग करेंगे जहां आप सदस्यों को उस क्रम में संदर्भित करना चाहते हैं जिसे आपने उन्हें संग्रहीत किया था और आप स्वयं आइटम के बजाय किसी स्थिति द्वारा उन्हें एक्सेस कर रहे हैं।

एक हैशट एक डिक्शनरी की तरह है कि आइटम ही कुंजी के साथ-साथ मूल्य भी है, ऑर्डर की गारंटी नहीं है।

आप एक HashSet का उपयोग करेंगे जहाँ आप जाँचना चाहते हैं कि कोई वस्तु संग्रह में है


1
स्पष्ट करने के लिए, अगर किसी और ने पहली नज़र में गलत पढ़ा है - Listएक आदेश बनाए रखता है (यानी जब चीजें जोड़ी गई थीं), लेकिन स्वचालित रूप से आइटम सॉर्ट नहीं करता है। आपको कॉल .Sortया उपयोग करना होगा SortedList
प्रातः

1

यदि आप इन डेटा संरचनाओं को डेटा-संचालित विकास में वास्तविक उपयोग के लिए लागू करने का निर्णय लेते हैं, तो डेटा सफाई और माइग्रेशन के लिए HashSet डेटा एडाप्टर स्रोतों के विरुद्ध प्रतिकृति का परीक्षण करने में बहुत मददगार है।

इसके अलावा, यदि DataAnnotations वर्ग का उपयोग कर रहे हैं, तो कोई वर्ग गुणों पर मुख्य तर्क को लागू कर सकता है और एक HashSet के साथ एक प्राकृतिक सूचकांक (क्लस्टर किए गए या नहीं) को प्रभावी ढंग से नियंत्रित कर सकता है, जहां एक सूची कार्यान्वयन में यह बहुत मुश्किल होगा।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.