.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#知识

  

  

相关文章
相关标签/搜索