.Net集合詳解

前言

  前面幾篇文章講了泛型、講了數組,都有提到集合,這一節重點對集合進行詳細解說。本文主要使用各類集合類型。以致於評估其性能,針對不一樣的場景選擇不一樣的集合使用。html

集合分類詳解

1、列表

  列表的建立c#

var    intList=new   List<int>();

 

  建立一個容量爲10 的集合數組

List<int>   intList=new   List<int>(10);

 

  列表初始值設定項數據結構

 

var intList = new List<int>() { 1,2};

 

  添加元素(經過使用Add方法進行元素添加)性能

var    intList=new   List<int>();

inList.Add(1);

var intList = new List<int>();

intList.AddRange(new List<int>(){ 1,2,3});

 

  插入元素(使用insert方法插入元素)學習

var intList = new List<int>();

intList.Insert(3, 3);

var intList = new List<int>();

intList.InsertRange(3, new List<int>() { 1,2,3});

 

  訪問元素(經過下表去實現訪問或者循環遍歷)spa

var intList = new List<int>();

    intList.AddRange( new List<int>() { 1,2,3});

    var answer = intList[2];

    foreach (var item in intList)

     {

       Console.WriteLine(item);

 }

 

  刪除元素(經過RemoveAt指定刪除某一位置的值)code

var intList = new List<int>();

intList.AddRange( new List<int>() { 1,2,3,4});

intList.RemoveAt(3);

 

  搜索(經過IndexOf訪問指定位置的值,可使用的方法IndexOf()LastIndexOf()FindLastIndex()Find()FindLast())htm

var intList = new List<int>();

intList.AddRange( new List<int>() { 1,2,3,4});

int indenx = intList.IndexOf(3);

 

2、隊列

  隊列是其元素以先進先出FirstIn,FirstOut,FIFO)的方式來處理的集合,先放入隊列中的元素會先讀取。隊列的例子比比皆是。排隊買票,食堂排隊打飯,先到先買,先到先打飯。blog

       

 

  隊列使用System.Collections.Generic命名空間中的泛型類Queue<T>來實現的。這個類型相似於List<T>。隊列類使用Enqueue()方法在隊列的一段插入元素,使用Dequeue()方法在另外一端讀取元素並刪除。

 

Queue<string> qa = new Queue<string>();

 qa.Enqueue("第一個進");

qa.Dequeue();

 

  其中使用Count()返回隊列中的元素總數,使用Peek()方法從隊列頭部讀取一個元素,但不刪除它。使用TrimExcess()方法從新設置隊列的容量,Dequeue()雖然刪除了元素,但不會從新設置容量。要從隊列頭部去除空元素,應使用TrimExcess()方法

3、

  棧是與隊列很是類似的另外一個容器,知識使用不一樣的方法訪問棧,並且棧的元素屬於最後添加的元素最早讀取也就是後進先出(LastIn,FirstOut,LIFO)。

       

 

  與Queue<T>相似,棧使用Stack<T>來實現,其中Push()在棧中添加元素,用Pop()方法獲取最近添加的元素。

Stack<string> qa = new Stack<string>();

qa.Push("第一個進");

qa.Pop();

 

  其中其餘方法與Queue<T>相似,使用Count()返回隊列中的元素總數,使用Peek()方法從隊列頭部讀取一個元素,但不刪除它。使用Contains()肯定某個元素是否存在於棧中,存在則返回True

 

4、有序列表

  若是須要基於鍵對所需的集合進行排序,就可使用SortedList<TKey,TValue>類。這個類按照鍵給的元素排序,這個集合中的值和鍵均可以使用任意類型。

  下面先建立一個空列表,而後經過Add()方法進行添加元素。而後輸出結果。咱們看下圖能夠發現自動幫咱們已經排序好了而後輸出的。

static void Main(string[] args)

        {

            var test = new SortedList<string, string>();

            test.Add("First","Code1");

            test.Add("Two", "Code2");

            test.Add("A", "Code3");

            foreach (var item in test)

            {

                Console.WriteLine(item.Key+":"+ item.Value);

            }

        }

 

 

5、字典

  字典表示一種複雜的數據結構,這種數據結構容許按照某個鍵來訪問元素。字典也稱爲映射或散列表。字典的主要特性是能根據鍵快速查找值。也能夠自由添加和刪除元素,這有點像List<T>,但沒有在內存中移動後續元素的性能開銷。

字典的初始化:

var dict = new Dictionary<int, string>() { {1,"第一個" },{2,"第二" } };

添加和輸出訪問

  dict.Add( 3,"第一個" );

    foreach (var item in dict)

    {

        Console.WriteLine("Key:"+item.Key+" Value:"+ item.Value);

}

 

  有序字典SortedDictionary<TKey,TValue>是一個二叉搜索樹,其中的元素根據建排序。和前面講的SortedList<TKey,TValue>的功能相似。可是SortedList<TKey,TValue>是基於數組的列表,而有序字典類爲一個字典。多以它們也有不一樣之處:

    •  SortedList<TKey,TValue>使用的內存比SortedDictionary<TKey,TValue>
    •  SortedDictionary<TKey,TValue>的元素插入和刪除比較快
    •  在用已排好序的數據填充集合時,若不須要修改容量,SortedList<TKey,TValue>就比較快

6、

  包含不重複元素的的集合稱爲(set)」.Net Core 包含兩個集(HashSet<T>SortedSet<T>),它們都實現ISet<T>接口,HashSet<T>集包含不重複元素的無序列表,SortedSet<T>集包含不重複元素的有序列表。

  ISet<T>接口提供的方法能夠建立合集、交集,或者給出一個集是另外一個集的超集或子集的信息。

       

 static void Main(string[] args)
        {
            var teams = new HashSet<string>() { "one","two","three"};
            var teams1= new HashSet<string>() { "開始","one", "two", "three" };

            //Add方法若是集中存在該元素則不添加,返回bool值
            if (!teams.Add("one"))
            {
                Console.WriteLine("one 已經存在集中");
            }

            //IsSubsetOf方法判斷teams集合中的元素是否都包含在teams1中,返回bool值
            if (teams.IsSubsetOf(teams1))
            {
                Console.WriteLine("teams中的值都包含在teams1中");
            }
 

            //IsSupersetOf方法判斷teams1集合是不是teams集合超集,返回bool值
            if (teams1.IsSupersetOf(teams))
            {
                Console.WriteLine("teams1是teams的超集");
            }


            //Overlaps方法判斷teams集合與teams是否存在重疊的元素,返回bool值
            if (teams.Overlaps(teams1))
            {
                Console.WriteLine("teams與teams1有重疊元素");
            }

        }

 

總結

  許多的集合都提供了相同的功能,例如SortedList類與SortedDictionary類的功能幾乎徹底相同。可是其性能經常差異很是巨大,一個集合使用的內存少,另外一個元素檢索起來速度快,在MSDN文檔中,集合的方法經常有性能的提示,給出以O記號表示的操做時間:

    •  O(1)
    •  O(log n)
    •  O(n)

  O(1)表示不管集合中有多少數據項,這個操做須要的時間都不變,例如,ArrayList類的Add()方法就具備這個行爲,不管列表有多少個集合,在列表末尾添加一個新元素的時間都相同。

  O(n)表示對於集合執行一個操做須要的時間最壞的狀況是N,若是須要從新給集合分配內存,ArrayList類的Add()方法就是一個O(n)操做。改變容量,須要複製列表,複製的時間隨元素的增長而線性的增長。

  O(log n)表示操做須要的時間隨集合中元素的增長而增長,但每一個元素要增長的時間不是線性的,而是呈對數曲線。在集合中執行插入操做時,SortedDictionary<TKey,TValue>集合類具備O(log n)行爲,而SortedList<TKey,TValue>集合具備O(n)行爲,這裏SortedDictionary<TKey,TValue>集合類就要快的多,由於樹形結構中插入元素的效率比列表高的多。

  下面表格中則列出了集合類及其執行不一樣操做的性能。可使用這個表選擇性能最佳的集合類進行使用。

集合

Add

Insert

Remove

Item

Sort

Find

List<T>

若是集合必須重置大小就是O(1)O(n)

O(n)

O(n)

O(1)

O(n log n)最壞狀況O(n^2)

O(n)

Stack<T>()

Push(),若是棧必須重置大小,就是O(1)O(n)

no

Pop(),O(1)

no

no

no

Queue<T>(列隊)

Enqueue(),若是棧必須重置大小,就是O(1)O(n)

no

Dequeu(),O(1)

no

no

no

HastSet<T>(無序列表)

若是棧必須重置大小,就是O(1)O(n)

Add()

O(1)O(n)

O(1)

no

no

no

LinkedList<T>(鏈表)

AddLast(),O(1)

AddAfter(),O(1)

O(1)

no

no

O(n)

 


 

      最糟糕的是人們在生活中常常受到錯誤志向的阻礙而不自知,真到擺脫了那些阻礙時才能明白過來。——歌德

 

 c#基礎知識詳解系列

 

歡迎你們掃描下方二維碼,和我一塊兒學習更多的C#知識

  

  

相關文章
相關標籤/搜索