点击上方蓝字↑↑↑,轻松 集合是.NETFCL(FramworkClassLibrary)中很重要的一部分,也是我们开发当中最常用到的功能之一,几乎是无处不在。俗话说知其然,知其所以然,平常看到IEnumrabl,IEnumrator,ICollction是不是知道他们之间各自的区别?除了List和Dictionary以外,你还用过哪些其它的集合类?废话少说,今天我们就来看一些这些定义集合类的接口以及他们的实现。集合接口 先来看一下,FCL为我们提供了哪些接口: IEnumrabl和IEnumbrator publicintrfacIEnumrator{boolMovNxt();objctCurrnt{gt;}voidRst();} IEnumrator定义了我们遍历集合的基本方法,以便我们可以实现单向向前的访问集合中的每一个元素。而IEnumrabl只有一个方法GtEnumrator即得到遍历器。 publicintrfacIEnumrabl{IEnumratorGtEnumrator();} 注意:我们经常用的forach即是一种语法糖,实际上还是调用Enumrator里面的Currnt和MovNxt实现的遍历功能。 Liststringlist=nwListstring(){Jss,Chlo,Li,Jim,XiaoJun};//Itratthlistbyusingforachforach(varbuddyinlist){Consol.WritLin(buddy);}//ItratthlistbyusingnumratorListstring.Enumratornumrator=list.GtEnumrator();whil(numrator.MovNxt()){Consol.WritLin(numrator.Currnt);} 上面的代码中用到的forach和numrator到IL中最后都会被翻译成numrator的MovNxt和Currnt。 IEnumrabl是一个很有用的接口,实现它的好处包括:1.支持forach语句2.作为一个标准的集合类与其它类库进行交互3.满足更复杂的集合接口的需求4.支持集合初始化器 当然实现的方法也有很多,如下:1.如果我们集合是通过封装其它集合类而来的,那么我们可以直接返回这个集合的numrator2.通过yildrturn来返回3.实现我们自己的IEnumrator来实现 这里给大家演示一下如何通过yild来实现返回numrator publicclassBuddyList:IEnumrabl{privatstring[]data=nwstring[]{Jss,Chlo,Li,Jim,XiaoJun};publicIEnumratorGtEnumrator(){forach(varstrindata){yildrturnstr;}}}varmyBuddis=nwBuddyList();forach(varstrinmyBuddis){Consol.WritLin(str);} ICollctionT和ICollction 从最上面第一张图我们可以知道,ICollction是直接继承自IEnumrabl。而实际上也是如此,我们可以说ICollction比IEnumrabl多支持一些功能,不仅仅只提供基本的遍历功能,还包括:1.统计集合和元素个数2.获取元素的下标3.判断是否存在4.添加元素到未尾5.移除元素等等。。。 ICollction与ICollctionT略有不同,ICollction不提供编辑集合的功能,即Add和Rmov。包括检查元素是否存在Contains也不支持。 IListT和IList IList则是直接继承自ICollction和IEnumrabl。所以它包括两者的功能,并且支持根据下标访问和添加元素。IndxOf,Insrt,RmovAt等等。我们可以这样说,IEnumrabl支持的功能最少,只有遍历。而ICollction支持的功能稍微多一点,不仅有遍历还有维护这个集合的功能。而IList是最全的版本。 IRadOnlyListT 这个是在Framwork4.5中新增的接口类型,可以被看作是IListT的缩减版,去掉了所有可能更改这个集合的功能。比如:Add,RmovAt等等。 IDictionaryTKy,TValu IDictionary提供了对键值对集合的访问,也是继承了ICollctionT和IEnumrabl,扩展了通过Ky来访问和操作数据的方法。 关联性泛型集合类 关联性集合类即我们常说的键值对集合,允许我们通过Ky来访问和维护集合。我们先来看一下FCL为我们提供了哪些泛型的关联性集合类:1.DictionaryTKy,TValu2.SortdDictionaryTKy,TValu3.SortdListTKy,TValuDictionaryTKy,TValu DictionaryTKy,TValu可能是我们最常用的关联性集合了,它的访问,添加,删除数据所花费的时间是所有集合类里面最快的,因为它内部用了Hashtabl作为存储结构,所以不管存储了多少键值对,查询/添加/删除所花费的时间都是一样的,它的时间复杂度是O(1)。 DictionaryTKy,TValu优势是查找插入速度快,那么什么是它的劣势呢?因为采用Hashtabl作为存储结构,就意味着里面的数据是无序排列的,所以想按一定的顺序去遍历DictionaryTKy,TValu里面的数据是要费一点工夫的。 作为TKy的类型必须实现GtHashCod()和Equals()或者提供一个IEqualityComparr,否则操作可能会出现问题。 SortdDictioanryTKy,TValu SortdDictionaryTKy,TValu和DictionaryTKy,TValu大致上是类似的,但是在实现方式上有一点点区别。SortdDictionaryTKy,TValu用二叉树作为存储结构的。并且按ky的顺序排列。那么这样的话SortdDictionaryTKy,TValu的TKy就必须要实现IComparablTKy。如果想要快速查询的同时又能很好的支持排序的话,那就使用SortdDictionary吧。 SortdListTKy,TValu SortdListTKy,TValu是另一个支持排序的关联性集合。但是不同的地方在于,SortdList实际是将数据存存储在数组中的。也就是说添加和移除操作都是线性的,时间复杂度是O(n),因为操作其中的元素可能导致所有的数据移动。但是因为在查找的时候利用了二分搜索,所以查找的性能会好一些,时间复杂度是O(logn)。所以推荐使用场景是这样地:如果你想要快速查找,又想集合按照ky的顺序排列,最后这个集合的操作(添加和移除)比较少的话,就是SortdList了。 非关联性泛型集合类 非关联性集合就是不用ky操作的一些集合类,通常我们可以用元素本身或者下标来操作。FCL主要为我们提供了以下几种非关联性的泛型集合类。1.ListT2.LinkdListT3.HashStT4.SortdStT5.StackT6.QuuTListT 泛型的List类提供了不限制长度的集合类型,List在内部维护了一定长度的数组(默认初始长度是4),当我们插入元素的长度超过4或者初始长度的时候,会去重新创建一个新的数组,这个新数组的长度是初始长度的2倍(不永远是2倍,当发现不断的要扩充的时候,倍数会变大),然后把原来的数组拷贝过来。所以如果知道我们将要用这个集合装多少个元素的话,可以在创建的时候指定初始值,这样就避免了重复的创建新数组和拷贝值。 另外的话由于内部实质是一个数组,所以在List的未必添加数据是比较快的,但是如果在数据的头或者中间添加删除数据相对来说更低效一些因为会影响其它数据的重新排列。 LinkdListT LinkdList在内部维护了一个双向的链表,也就是说我们在LinkdList的任何位置添加或者删除数据其性能都是很快的。因为它不会导致其它元素的移动。一般情况下List已经够我们使用了,但是如果对这个集合在中间的添加删除操作非常频繁的话,就建议使用LinkdList。 HashStT HashSt是一个无序的能够保持唯一性的集合。我们也可以把HashSt看作是DictionaryTKy,TValu,只不过TKy和TValu都指向同一个对象。HashSt非常适合在我们需要保持集合内元素唯一性但又不需要按顺序排列的时候。 HashSt不支持下标访问。 SortdStT SortdSt和HashSt,就像SortdDictionary和Dictionary一样,还记得这两个的区别么?SortdSt内部也是一个二叉树,用来支持按顺序的排列元素。 StackT 后进先出的队列 不支持按下标访问 QuuT 先进先出的队列 不支持按下标访问 非泛型类集合 泛型集合类是在.NET2.0的时候出来的,也就是说在1.0的时候是没有这么方便的东西的。现在基本上我们已经不使用这些集合类了,除非在做一些和老代码保持兼容的工作的时候。来看看1.0时代的.NET程序员们都有哪些集合类可以用。1.ArraryList后来被ListT替代。1.HashTabl后来被DictionaryTKy,TValu替代。2.Quu后来被QuuT替代。3.SortdList后来被SortdListT替代。4.Stack后来被StackT替代。线程安全的集合类1.ConcurrntQuu线程安全版本的Quu2.ConcurrntStack线程安全版本的Stack3.ConcurrntBag线程安全的对象集合4.ConcurrntDictionary线程安全的Dictionary5.BlockingCollction.NET为我们提供的集合类是我们很常用的工具类之一,希望这篇文章能够帮助大家更好的认识这些集合类。当然,个人感觉还有不完善的地方,比如说HashTabl和BinarySarchTr就没有细究下去,包括单向链表和双向链表之间的对比本文也没有提及。感兴趣的朋友可以深入了解一下。 作者:Jss 出处:北京治愈白癜风的医院哪里最好北京皮肤病医院
|