前言

  前面几篇文章讲了泛型、讲了数组,都有提到集合,这一节重点对集合进行详细解说。本文主要使用各种集合类型。以至于评估其性能,针对不同的场景选择不同的集合使用。

集合分类详解

一、列表

  列表的创建

var    intList=new   List<int>();

  创建一个容量为10 的集合

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

  列表初始值设定项

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

  添加元素(通过使用Add方法进行元素添加)

var    intList=new   List<int>();

inList.Add();

var intList = new List<int>();

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

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

var intList = new List<int>();

intList.Insert(, );

var intList = new List<int>();

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

  访问元素(通过下表去实现访问或者循环遍历)

var intList = new List<int>();

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

    var answer = intList[];

    foreach (var item in intList)

     {

       Console.WriteLine(item);

 }

  删除元素(通过RemoveAt指定删除某一位置的值)

var intList = new List<int>();

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

intList.RemoveAt();

  搜索(通过IndexOf访问指定位置的值,可以使用的方法IndexOf()、LastIndexOf()、FindLastIndex()、Find()、FindLast())

var intList = new List<int>();

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

int indenx = intList.IndexOf();

二、队列

  队列是其元素以先进先出(FirstIn,FirstOut,FIFO)的方式来处理的集合,先放入队列中的元素会先读取。队列的例子比比皆是。排队买票,食堂排队打饭,先到先买,先到先打饭。

       

  队列使用System.Collections.Generic命名空间中的泛型类Queue<T>来实现的。这个类型类似于List<T>。队列类使用Enqueue()方法在队列的一段插入元素,使用Dequeue()方法在另一端读取元素并删除。

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

 qa.Enqueue("第一个进");

qa.Dequeue();

  其中使用Count()返回队列中的元素总数,使用Peek()方法从队列头部读取一个元素,但不删除它。使用TrimExcess()方法重新设置队列的容量,Dequeue()虽然删除了元素,但不会重新设置容量。要从队列头部去除空元素,应使用TrimExcess()方法

三、

  栈是与队列非常相似的另一个容器,知识使用不同的方法访问栈,而且栈的元素属于最后添加的元素最先读取也就是后进先出(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

四、有序列表

  如果需要基于键对所需的集合进行排序,就可以使用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);

            }

        }

五、字典

  字典表示一种复杂的数据结构,这种数据结构允许按照某个键来访问元素。字典也称为映射或散列表。字典的主要特性是能根据键快速查找值。也可以自由添加和删除元素,这有点像List<T>,但没有在内存中移动后续元素的性能开销。

字典的初始化:

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

添加和输出访问

  dict.Add( ,"第一个" );

    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>就比较快

六、

  包含不重复元素的的集合称为”集(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#知识

  

.Net集合详解的更多相关文章

  1. Java 集合详解

    一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型.为了满足这些常规的编程需要,我们要 ...

  2. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  3. Java集合详解6:TreeMap和红黑树

    Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...

  4. Java集合详解3:Iterator,fail-fast机制与比较器

    Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...

  5. 【转载】Java 集合详解

    转载:https://www.cnblogs.com/ysocean/p/6555373.html 一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段 ...

  6. Java集合详解8:Java集合类细节精讲,细节决定成败

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  7. Java集合详解7:一文搞清楚HashSet,TreeSet与LinkedHashSet的异同

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  8. Java集合详解6:这次,从头到尾带你解读Java中的红黑树

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  9. Java集合详解4:一文读懂HashMap和HashTable的区别以及常见面试题

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  10. Java集合详解3:一文读懂Iterator,fail-fast机制与比较器

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

随机推荐

  1. Java 位域

    Java位域 这个概念是在 Effective Java中了解到的, 可以通过EnumSet来代替位域这种方式表达. 并不是很常见的概念, 因此记录下. 如果在这之前恰好了解过 bitmap这种数据结 ...

  2. Singleton and Prototype Bean Scope in Spring

    Scope描述的是Spring容器如何新建Bean的实例的. 1> Singleton: 一个Spring容器只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例. 2> ...

  3. docker命令总结

    用 docker pull 拉取镜像 root@lishichao-virtual-machine:~# docker pull hello-world Using default tag: late ...

  4. 5分钟快速部署ownCloud私有云盘存储系统

    ownCloud 是一个开源免费专业的私有云存储项目,它能帮你快速在个人电脑或服务器上架设一套专属的私有云文件同步网盘,可以像 Dropbox 那样实现文件跨平台同步.共享.版本控制.团队协作等等.o ...

  5. Linux权限_用户_和用户组

    Linux中用户UID就判断操作系统中用户的身份. Centos7.x: 0:超级管理员 1-999:系统用户(包含Linux中自带服务) 1000以上   普通用户 Centos6.x : Root ...

  6. c++ 组合

    组合 题目描述 已知一个一维数组a1..n,又已知一整数m. 如能使数组a中任意几个元素之和等于m,则输出YES,反之则为NO. 输入 输入包括两行,第一行包含两个整数n m(1<=n<2 ...

  7. 利用Python模拟GitHub登录

    最近学习了Fiddler抓包工具的简单使用,通过抓包,我们可以抓取到HTTP请求,并对其进行分析.现在我准备尝试着结合Python来模拟GitHub登录. Fiddler抓包分析 首先,我们想要模拟一 ...

  8. 新手上路—Java的"瑞士军刀"

    “ Jodd 是一个开源的 Java 工具集, 包含一些实用的工具类和小型框架.简单,却很强大!这在我们的日常开发工作中,无疑是如虎添翼,事半功倍. Jodd = Tools + IoC + MVC ...

  9. CDQZ集训DAY4 日记

    早上起来之后发现座位被zzh占了,得知座位改为先来后到,什么鬼…… 于是去了另一个有耳机的机房,然而并没有什么卵用. T1上来感觉很有意思,先切50分再说.T2好像是原题的说,切了原题30分后大胆猜测 ...

  10. 【并查集】连接格点-C++

    连接格点 描述 有一个M行N列的点阵,相邻两点可以相连.一条纵向的连线花费一个单位,一条横向的连线花费两个单位.某些点之间已经有连线了,试问至少还需要花费多少个单位才能使所有的点全部连通. 输入 第一 ...