日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#集合类型总结和性能分析

發(fā)布時間:2023/12/10 C# 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#集合类型总结和性能分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C#集合類型概述

集合是.NET FCL(Framework Class Library)中很重要的一部分。所有的集合類都繼承自IEnumerable。集合類總體可分為一下幾類:關(guān)聯(lián)/非關(guān)聯(lián)型集合,順序/隨機訪問集合,順序/無序集合,泛型/非泛型集合,線程安全集合。

各集合類底層接口關(guān)系圖

泛型與非泛型集合類的分析

  • 泛型集合是類型安全的,基于固定的泛型T,運行時不需要像非泛型的執(zhí)行Object和具體類型的類型轉(zhuǎn)換。
  • 泛型集合的效率相對較高。
  • 兩者都能實現(xiàn)數(shù)據(jù)存儲,不同的是泛型只能存放T類型數(shù)據(jù),有運行時檢測,而非泛型的都轉(zhuǎn)化為Object存儲,能存儲任意類型,包括值類型,會帶來裝箱拆箱的性能損耗,同時都是Object類型(弱類型)編譯時無法類型檢測,運行時會導(dǎo)致類型不一致的安全性問題。

  • 具體接口/類分析

    CollectionBase/DictionaryBase的目的

  • 都是抽象類,不能實例化;
  • 目的是提供給用戶自定義實現(xiàn)強類型的集合,解決一般非泛型集合的弱類型不安全的問題。
  • IEnumerator/IEnumerable

    IEnumerator定義了我們遍歷集合的基本方法,以便我們可以實現(xiàn)單向向前的訪問集合中的每一個元素。?所有的集合類都繼承了IEnumerator接口,包括String類。而IEnumerable只有一個方法GetEnumerator即得到遍歷器。

    ICollection<T>和ICollection

    從最上面第一張圖我們可以知道,ICollection是直接繼承自IEnumerable。而實際上也是如此,我們可以說ICollection比IEnumerable多支持一些功能,不僅僅只提供基本的遍歷功能,還包括:

    統(tǒng)計集合和元素個數(shù)?
    獲取元素的下標?
    判斷是否存在?
    添加元素到未尾?
    移除元素等等。。。?
    ICollection 與ICollection<T> 略有不同,ICollection不提供編輯集合的功能,即Add和Remove。包括檢查元素是否存在Contains也不支持。

    IList和IList

    IList則是直接繼承自ICollection和IEnumerable。所以它包括兩者的功能,并且支持根據(jù)下標訪問和添加元素。IndexOf, Insert, RemoveAt等等。我們可以這樣說,IEnumerable支持的功能最少,只有遍歷。而ICollection支持的功能稍微多一點,不僅有遍歷還有維護這個集合的功能。而IList是最全的版本。

    IReadOnlyList<T>

    這個是在Framework4.5中新增的接口類型,可以被看作是IList的縮減版,去掉了所有可能更改這個集合的功能。比如:Add, RemoveAt等等。

    IDictionary<TKey,TValue>

    IDictionary提供了對鍵值對集合的訪問,也是繼承了ICollection<T>和IEnumerable,擴展了通過Key來訪問和操作數(shù)據(jù)的方法。


    關(guān)聯(lián)性泛型集合類

    關(guān)聯(lián)性集合類即我們常說的鍵值對集合,允許我們通過Key來訪問和維護集合。我們先來看一下 FCL為我們提供了哪些泛型的關(guān)聯(lián)性集合類:

    Dictionary <TKey,TValue>?
    SortedDictionary<TKey,TValue>?
    SortedList<TKey,TValue>?
    Dictionary<TKey,TValue>

    Dictionary<TKey,TValue>

    是我們最常用的關(guān)聯(lián)性集合了,它的訪問,添加,刪除數(shù)據(jù)所花費的時間是所有集合類里面最快的,因為它內(nèi)部用了Hashtable作為存儲結(jié)構(gòu),所以不管存儲了多少鍵值對,查詢/添加/刪除所花費的時間都是一樣的,它的時間復(fù)雜度是O(1)。

    Dictionary<TKey,TValue>優(yōu)勢是查找插入速度快,那么什么是它的劣勢呢?因為采用Hashtable作為存儲結(jié)構(gòu),就意味著里面的數(shù)據(jù)是無序排列的,所以想按一定的順序去遍歷Dictionary<TKey,TValue>里面的數(shù)據(jù)是要費一點工夫的。

    作為TKey的類型必須實現(xiàn)GetHashCode()和Equals() 或者提供一個IEqualityComparer,否則操作可能會出現(xiàn)問題。

    SortedDictioanry<TKey,TValue>

    SortedDictionary<TKey,TValue>和Dictionary<TKey,TValue>大致上是類似的,但是在實現(xiàn)方式上有一點點區(qū)別。SortedDictionary<TKey,TValue>用二叉樹作為存儲結(jié)構(gòu)的。并且按key的順序排列。那么這樣的話SortedDictionary<TKey,TValue>的TKey就必須要實現(xiàn)IComparable<TKey>。如果想要快速查詢的同時又能很好的支持排序的話,那就使用SortedDictionary吧。

    SortedList<TKey,TValue>

    SortedList<TKey,TValue>是另一個支持排序的關(guān)聯(lián)性集合。但是不同的地方在于,SortedList實際是將數(shù)據(jù)存存儲在數(shù)組中的。也就是說添加和移除操作都是線性的,時間復(fù)雜度是O(n),因為操作其中的元素可能導(dǎo)致所有的數(shù)據(jù)移動。但是因為在查找的時候利用了二分搜索,所以查找的性能會好一些,時間復(fù)雜度是O(log n)。所以推薦使用場景是這樣地:如果你想要快速查找,又想集合按照key的順序排列,最后這個集合的操作(添加和移除)比較少的話,就是SortedList了。


    非關(guān)聯(lián)性泛型集合類

    非關(guān)聯(lián)性集合就是不用key操作的一些集合類,通常我們可以用元素本身或者下標來操作。FCL主要為我們提供了以下幾種非關(guān)聯(lián)性的泛型集合類。

    List<T>?
    LinkedList<T>?
    HashSet<T>?
    SortedSet<T>?
    Stack<T>?
    Queue<T>?
    List<T>

    泛型的List 類提供了不限制長度的集合類型,List在內(nèi)部維護了一定長度的數(shù)組(默認初始長度是4),當我們插入元素的長度超過4或者初始長度 的時候,會去重新創(chuàng)建一個新的數(shù)組,這個新數(shù)組的長度是初始長度的2倍(不永遠是2倍,當發(fā)現(xiàn)不斷的要擴充的時候,倍數(shù)會變大),然后把原來的數(shù)組拷貝過來。所以如果知道我們將要用這個集合裝多少個元素的話,可以在創(chuàng)建的時候指定初始值,這樣就避免了重復(fù)的創(chuàng)建新數(shù)組和拷貝值。

    另外的話由于內(nèi)部實質(zhì)是一個數(shù)組,所以在List的未必添加數(shù)據(jù)是比較快的,但是如果在數(shù)據(jù)的頭或者中間添加刪除數(shù)據(jù)相對來說更低效一些因為會影響其它數(shù)據(jù)的重新排列。

    LinkedList<T>

    LinkedList在內(nèi)部維護了一個雙向的鏈表,也就是說我們在LinkedList的任何位置添加或者刪除數(shù)據(jù)其性能都是很快的。因為它不會導(dǎo)致其它元素的移動。一般情況下List已經(jīng)夠我們使用了,但是如果對這個集合在中間的添加刪除操作非常頻繁的話,就建議使用LinkedList。

    HashSet<T>

    HashSet是一個無序的能夠保持唯一性的集合。我們也可以把HashSet看作是Dictionary<TKey,TValue>,只不過TKey和TValue都指向同一個對象。HashSet非常適合在我們需要保持集合內(nèi)元素唯一性但又不需要按順序排列的時候。

    HashSet不支持下標訪問。

    SortedSet<T>

    SortedSet和HashSet,就像SortedDictionary和Dictionary一樣,還記得這兩個的區(qū)別么?SortedSet內(nèi)部也是一個二叉樹,用來支持按順序的排列元素。

    Stack<T>

    后進先出的隊列?
    不支持按下標訪問

    Queu<T>

    先進先出的隊列?
    不支持按下標訪問


    推薦使用場景


    非泛型類集合

    泛型集合類是在.NET2.0的時候出來的,也就是說在1.0的時候是沒有這么方便的東西的。現(xiàn)在基本上我們已經(jīng)不使用這些集合類了,除非在做一些和老代碼保持兼容的工作的時候。來看看1.0時代的.NET程序員們都有哪些集合類可以用。

    ArraryList?
    后來被List<T>替代。

    HashTable 后來被Dictionary<TKey,TValue>替代。?
    Queue 后來被Queue<T>替代。?
    SortedList 后來被SortedList<T>替代。?
    Stack 后來被Stack<T>替代。

    線程安全的集合類

    ConcurrentQueue 線程安全版本的Queue?
    ConcurrentStack線程安全版本的Stack?
    ConcurrentBag線程安全的對象集合?
    ConcurrentDictionary線程安全的Dictionary?
    BlockingCollection


    .NET為我們提供的集合類是我們很常用的工具類之一,希望這篇文章能夠幫助大家更好的認識這些集合類。當然,個人感覺還有不完善的地方,比如說HashTable和Binary Search Tree就沒有細究下去,包括單向鏈表和雙向鏈表之間的對比本文也沒有提及。感興趣的朋友可以深入了解一下。

    總結(jié)

    以上是生活随笔為你收集整理的C#集合类型总结和性能分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。