ArrayList बनाम सूची <> C # में


412

C ArrayListऔर List<># में क्या अंतर है?

क्या यह केवल List<>एक प्रकार है जबकि ArrayListनहीं है?



5
यह एक करीबी प्रश्न है, लेकिन मुझे लगता है कि वास्तव में डुप्लिकेट नहीं है। यह List<>सामान्य रूप से के बारे में पूछता है , जबकि वह List<object>विशेष रूप से पूछता है
गोडेई

यह बहुत उपयोगी ब्लॉग मिला, यह मदद कर सकता है। सोचा मैं लिंक साझा करना चाहिए fintechexplained.blogspot.co.uk/2017/07/...
InfoLearner

जवाबों:


533

हाँ, बहुत ज्यादा। List<T>एक सामान्य वर्ग है। यह किसी विशिष्ट प्रकार के संचय मानों को या बिना कास्टिंग के object(जिसमें बॉक्सिंग / अनबॉक्सिंग ओवरहेड होता Tहै, जब ArrayListमामले में मूल्य प्रकार होता है)। ArrayListबस objectसंदर्भ संग्रहीत करता है । एक सामान्य संग्रह के रूप में, List<T>जेनेरिक IEnumerable<T>इंटरफ़ेस को लागू करता है और LINQ में आसानी से इस्तेमाल किया जा सकता है (बिना किसी आवश्यकता Castया OfTypeकॉल के)।

ArrayListउन दिनों से संबंधित है जिनमें C # की जेनरिक नहीं थी। इसके पक्ष में पदावनत किया जाता है List<T>। आपको ArrayList.NET> = 2.0 को लक्षित करने वाले नए कोड में उपयोग नहीं करना चाहिए, जब तक कि आपको इसका उपयोग करने वाले पुराने API के साथ इंटरफ़ेस न करना पड़े।


क्या आप यह समझाएंगे कि आपने "बॉक्सिंग" का इस्तेमाल क्यों किया और "कास्टिंग" का नहीं? यहां क्या मुक्केबाजी होती है? क्या वस्तुओं का आवंटन / निपटारा किया जाता है?
बेंजामिन ग्रुएनबाम

2
@BenjaminGruenbaum आप सही हैं कि कास्टिंग अधिक सामान्य होगी। उस ने कहा, रनटाइम पर असली अंतर तब होता है जब आप मूल्य प्रकारों के साथ काम कर रहे होते हैं (जब मैंने "बॉक्सिंग" लिखा था, तो मैंने ऐसा मान लिया था)। संदर्भ प्रकारों के लिए, व्यवहार प्रभावी रूप ArrayListसे रनटाइम के समान है। सांख्यिकीय रूप से यद्यपि, इसके साथ एक कलाकार की आवश्यकता होगी ArrayList
मेहरदाद अफश्री

मैं सोच रहा था कि क्या ढांचा टी को "ऑब्जेक्ट" प्रकार का होना चाहिए, क्योंकि एरियरिस्ट ने स्पष्ट रूप से अनुमति दी है।
rajibdotnet


@ Ant_222, यह ब्लॉग लगभग 15 साल पहले लिखा गया था। मुझे लगता है कि पिछले दशक में सबूतों से पता चला है कि जेनेरिक हानिकारक नहीं हैं। :)
स्कॉट एडम्स

101

का उपयोग करके List<T>आप कास्टिंग त्रुटियों को रोक सकते हैं। रनटाइम कास्टिंग त्रुटि से बचने के लिए यह बहुत उपयोगी है ।

उदाहरण:

यहां (उपयोग करके ArrayList) आप इस कोड को संकलित कर सकते हैं लेकिन बाद में आपको एक निष्पादन त्रुटि दिखाई देगी।

ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
 total += num; //-->Runtime Error
}

यदि आप उपयोग करते हैं List, तो आप इन त्रुटियों से बचते हैं:

List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
 total += num;
}

संदर्भ: MSDN


आप उस प्रकार की जाँच कर सकते हैं जब आप कास्टिंग त्रुटियों को रोकने के लिए ArrayList से खींचते हैं। अब दिन लोग ऑब्जेक्ट का उपयोग करते हैं, जिससे ArrayList की अब आवश्यकता नहीं है।
स्विच करें

1
i +1 को औचित्य देने के लिए लेकिन आप अभी भी कर सकते हैं यदि (संख्या int है) {} त्रुटियों से बचने के लिए अपनी सरणी सूची में {}
मीना गैब्रियल

कास्टिंग त्रुटियों और बॉक्सिंग ओवरहेड को रोकें। सामान्य रूप से बहुत अधिक जेनेरिक के कारण।
मंगल

26

उपरोक्त बिंदुओं को जोड़ने के लिए। का उपयोग करते हुए ArrayList64 बिट ऑपरेटिंग सिस्टम में 32 बिट ऑपरेटिंग सिस्टम में उपयोग करने की तुलना 2x स्मृति लेता है। इस बीच, जेनेरिक सूची List<T>की तुलना में बहुत कम मेमोरी का उपयोग किया जाएगा ArrayList

उदाहरण के लिए यदि हम ArrayList32-बिट में 19MB का उपयोग करते हैं तो 64-बिट में 39MB लगेगा। लेकिन अगर आपके पास List<int>32-बिट में 8MB की जेनेरिक सूची है , तो यह 64-बिट में केवल 8.1MB ही लेगा, जो कि ArrayList की तुलना में एक हूपिंग 481% अंतर है।

स्रोत: आदिम प्रकार और 64-बिट्स के लिए ArrayList की जेनेरिक सूची


5
यह केवल मूल्य प्रकारों के भंडारण के लिए सही है, संदर्भ प्रकारों के लिए नहीं। अंतर इस तथ्य के कारण है कि एक सरणी सूची में केवल संकेत हो सकते हैं, और डेटा को स्वयं कहीं और संग्रहीत करने की आवश्यकता होती है। दूसरी ओर, मूल्य प्रकारों को सीधे एक सूची में संग्रहीत किया जा सकता है।
रासमस डमगार्ड नीलसन

19

जोड़ने के लिए एक और अंतर थ्रेड सिंक्रोनाइज़ेशन के संबंध में है।

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

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

यहाँ अधिक जानकारी .Net फ्रेमवर्क में थ्रेड सिंक्रोनाइज़ेशन


मैं यह नहीं कह रहा हूं कि ArrayListअगर आपको इससे बचा जा सकता है तो आपको इसका उपयोग करना चाहिए, लेकिन यह एक मूर्खतापूर्ण कारण है। आवरण सभी के बाद पूरी तरह से वैकल्पिक है; यदि आपको लॉकिंग की आवश्यकता नहीं है या यदि आपको अधिक दानेदार नियंत्रण की आवश्यकता है, तो आवरण का उपयोग न करें।
थोरिन

1
यदि आप थ्रेड-सेफ्टी चाहते हैं, तो मैं सुझाव देता हूं कि ArrayList पर विचार करने से पहले System.Collections.Concurrent नाम स्थान देखें।
योको

15

सरल उत्तर है,

ArrayList गैर जेनेरिक है

  • यह एक ऑब्जेक्ट प्रकार है, इसलिए आप इसमें किसी भी डेटा प्रकार को संग्रहीत कर सकते हैं।
  • आप किसी भी मान (मान प्रकार या संदर्भ प्रकार) को ऐसे स्ट्रिंग, इंट, कर्मचारी और ऑब्जेक्ट को ArrayList में संग्रहीत कर सकते हैं। (नोट और)
  • बॉक्सिंग और अनबॉक्सिंग होगा।
  • सुरक्षित नहीं है।
  • यह अधिक पुराना है।

सूची सामान्य है

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

उदाहरण:

ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();

arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());


list.Add(1);
list.Add("String");                 // Compile-time Error
list.Add(new object());             // Compile-time Error

कृपया Microsoft आधिकारिक दस्तावेज़ पढ़ें : https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/

यहां छवि विवरण दर्ज करें

नोट : अंतर समझने से पहले आपको जेनरिक को जानना चाहिए: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/


4

ArrayListविभिन्न प्रकार के डेटा List<>का संग्रह है, जबकि अपनी स्वयं की समान प्रकार का संग्रह है।


3

ArrayListप्रकार सुरक्षित नहीं हैं, जबकि List<T>प्रकार सुरक्षित हैं। सरल :)।


2

प्रदर्शन को पहले से ही एक विभेदक कारक के रूप में कई उत्तरों में उल्लेख किया गया है, लेकिन " कितना धीमा है ArrayList?" "और" यह कुल मिलाकर धीमा क्यों है? ", नीचे एक नज़र है।

जब भी मूल्य प्रकार तत्वों के रूप में उपयोग किए जाते हैं, तो प्रदर्शन नाटकीय रूप से गिरता है ArrayList। केवल तत्वों को जोड़ने के मामले पर विचार करें। बॉक्सिंग के चलते - जैसा कि ArrayListऐड केवल objectपैरामीटर लेता है - कचरा कलेक्टर के साथ और अधिक काम करने के लिए शुरू हो जाता है List<T>

समय का अंतर कितना है? की तुलना में कम से कम कई बार धीमा List<T>। बस क्या कोड एक करने के लिए 10 मील पूर्णांक मानों को जोड़ने के साथ होता है पर एक नज़र डालें ArrayListबनाम List<T>: यहां छवि विवरण दर्ज करें

पीले रंग में हाइलाइट किए गए 'मीन' कॉलम में 5x का रन टाइम अंतर है । प्रत्येक के लिए किए गए कचरा संग्रह की संख्या में अंतर पर भी ध्यान दें, लाल रंग में हाइलाइट किया गया (जीसी / 1000 रन नहीं)।

प्रोफाइलर का उपयोग यह देखने के लिए कि जल्दी से क्या हो रहा है, यह दर्शाता है कि अधिकांश समय जीसीएस करने में खर्च किया जाता है, जैसा कि वास्तव में तत्वों को जोड़ने के लिए किया जाता है। नीचे दी गई भूरे रंग की पट्टियाँ गारबेज कलेक्टर गतिविधि को दर्शाती हैं: यहां छवि विवरण दर्ज करें

मैंने ऊपर के ArrayListपरिदृश्य के साथ यहाँ क्या हो रहा है, का एक विस्तृत विश्लेषण लिखा है https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/

इसी तरह के निष्कर्ष जेफरी रिक्टर द्वारा "सीएलआर के माध्यम से सी #" में हैं। अध्याय 12 (पीढ़ी) से:

[…] जब मैं अपने कंप्यूटर पर इस प्रोग्राम के रिलीज़ बिल्ड (अनुकूलन के साथ चालू) को संकलित और चलाता हूं, तो मुझे निम्न आउटपुट मिलता है।

00: 00: 01.6246959 (GCs = 6) सूची <Int32>
00: 00: 10.8555008 (GCs = 390) Int32 का ArrayList
00: 00: 02.5427847 (GCs / 4) सूची <स्ट्रिंग>
00: 00: 02.7944831 (GCs = 7) ) स्ट्रिंग के ArrayList

यहाँ आउटपुट से पता चलता है कि Int32 प्रकार के साथ जेनेरिक सूची एल्गोरिथ्म का उपयोग करना, Int32 के साथ गैर-जेनेरिक ArrayList एल्गोरिथ्म का उपयोग करने की तुलना में बहुत तेज़ है। वास्तव में, अंतर अभूतपूर्व है: 1.6 सेकंड बनाम लगभग 11 सेकंड। यह ~ 7 गुना तेज है ! इसके अलावा, ArrayList के साथ एक वैल्यू टाइप (Int32) का उपयोग करने से कई बॉक्सिंग ऑपरेशन होते हैं, जिसके परिणामस्वरूप 390 कचरा संग्रह होते हैं। इस बीच, सूची एल्गोरिदम को 6 कचरा संग्रह की आवश्यकता थी।


1

मुझे लगता है, के बीच के अंतर ArrayListऔर List<T>हैं:

  1. List<T>, जहां T मूल्य-प्रकार से अधिक तेज़ है ArrayList। ऐसा इसलिए है क्योंकि List<T>बॉक्सिंग / अनबॉक्सिंग (जहां T मूल्य-प्रकार है) से बचा जाता है।
  2. कई स्रोतों का कहना है - आमतौर पर ArrayListसिर्फ पिछड़ी संगतता के लिए उपयोग किया जाता है। (वास्तविक अंतर नहीं है, लेकिन मुझे लगता है कि यह महत्वपूर्ण नोट है)।
  3. ArrayListतब प्रतिभावान के साथ प्रतिबिंब आसान होता हैList<T>
  4. ArrayListहै IsSynchronizedसंपत्ति। इसलिए, सिंक्रोनाइज़्ड बनाना और उपयोग करना आसान है ArrayList। मुझे IsSynchronizedसंपत्ति नहीं मिली List<T>। यह भी ध्यान रखें कि इस प्रकार का सिंक्रनाइज़ेशन अपेक्षाकृत अक्षम है, एमएसडीएन ):

    var arraylist = new ArrayList();
    var arrayListSyncronized = ArrayList.Synchronized(arraylist
    Console.WriteLine($"syncronized {arraylist.IsSynchronized}");
    Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}");
    
    var list = new List<object>();
    var listSyncronized = ArrayList.Synchronized(list);
    Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
    Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
  5. ArrayListऐसी ArrayList.SyncRootसंपत्ति है जिसका उपयोग सिंक्रोनाइजेशन ( msdn ) के लिए किया जा सकता है । संपत्ति List<T>नहीं SyncRootहै, इसलिए यदि आप उपयोग करते हैं तो निम्नलिखित निर्माण में आपको किसी वस्तु का उपयोग करने की आवश्यकता है List<T>:

    ArrayList myCollection = new ArrayList();
    lock(myCollection.SyncRoot) //  ofcourse you can use another object for this goal
    {
        foreach (object item in myCollection)
        {
            // ...
        }
    }

0

जैसा कि .NET फ्रेमवर्क प्रलेखन में उल्लेख किया गया है

हम अनुशंसा नहीं करते हैं कि आप ArrayListनए विकास के लिए कक्षा का उपयोग करें । इसके बजाय, हम अनुशंसा करते हैं कि आप सामान्य List<T> वर्ग का उपयोग करें । ArrayListवर्ग वस्तुओं की विषम संग्रह धारण करने के लिए बनाया गया है। हालांकि, यह हमेशा सर्वश्रेष्ठ प्रदर्शन की पेशकश नहीं करता है। इसके बजाय, हम निम्नलिखित सलाह देते हैं:

  • वस्तुओं के विषम संग्रह के लिए, List<Object>(C # में) या List(Of Object)(Visual Basic में) प्रकार का उपयोग करें।
  • वस्तुओं के एक सजातीय संग्रह के लिए, List<T>कक्षा का उपयोग करें ।

यह भी देखें गैर सामान्य संग्रह नहीं किया जाना चाहिए

तालिका से पता चलता है कि गैर-सामान्य संग्रह प्रकारों को उनके सामान्य समकक्षों द्वारा कैसे बदला जा सकता है


-2

"सूची" का उपयोग करके आप कास्टिंग त्रुटियों को रोक सकते हैं। रनटाइम कास्टिंग त्रुटि से बचने के लिए यह बहुत उपयोगी है।

उदाहरण:

यहां (ArrayList का उपयोग करके) आप इस कोड को संकलित कर सकते हैं लेकिन बाद में आपको एक निष्पादन त्रुटि दिखाई देगी।

    // Create a new ArrayList


    System.Collections.ArrayList mixedList = new System.Collections.ArrayList();


    // Add some numbers to the list
    mixedList.Add(7);
    mixedList.Add(21);


    // Add some strings to the list
    mixedList.Add("Hello");
    mixedList.Add("This is going to be a problem");




    System.Collections.ArrayList intList = new System.Collections.ArrayList();
    System.Collections.ArrayList strList = new System.Collections.ArrayList();


    foreach (object obj in mixedList)
    {
        if (obj.GetType().Equals(typeof(int)))
        {
            intList.Add(obj);
        }
        else if (obj.GetType().Equals(typeof(string)))
        {
            strList.Add(obj);
        }
        else
        {
            // error.
        }
    }

तीन साल पहले दिए गए उत्तर-काल से परे यह क्या जोड़ता है? यह लगभग एक ही पाठ शब्दशः है, स्रोत से जुड़े बिना, ठीक से स्वरूपण के बिना, आदि
डगलस ज़ेरे

-3

मुझे अपने डेटा के बारे में जानने के लिए। यदि मैं दक्षता के आधार पर अपने कोड का विस्तार करना जारी रख रहा हूं, तो मुझे अपने डेटा w / o के हमेशा सही प्रकारों के बारे में सोचने के अनावश्यक कदम के रूप में सूची विकल्प चुनना होगा, विशेष रूप से 'कस्टम प्रकार' के बारे में। यदि मशीन अंतर को समझती है और इस पर निर्धारित कर सकती है कि मैं वास्तव में किस प्रकार के डेटा के साथ काम कर रही हूं, तो मुझे 'IF THEN ELSE' के निर्धारणों के दौरान रास्ते में समय क्यों बर्बाद करना चाहिए? मेरा दर्शन मेरे लिए मशीन पर काम करने के बजाय मशीन को काम करने देना है? विभिन्न ऑब्जेक्ट कोड कमांड के अनूठे अंतर को जानने से आपके कोड को कुशल बनाने में लंबा रास्ता तय होता है।

टॉम जॉनसन (एक प्रविष्टि ... एक बाहर निकलें)

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