【C# 数据结构】 泛型 集合ADT System.Collections.Generic
System.Collections.Generic
集合和数据结构
接口
ADT
IEnumerable 和IEnumberator
public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset(); }
IEnumerator定义了我们遍历集合的基本方法,以便我们可以实现单向向前的访问集合中的每一个元素。而IEnumerable只有一个方法GetEnumerator即得到遍历器。
public interface IEnumerable { IEnumerator GetEnumerator(); }
注意:我们经常用的foreach即是一种语法糖,实际上还是调用Enumerator里面的Current和MoveNext实现的遍历功能。
ICollection和ICollection
从最上面第一张图我们可以知道,ICollection是直接继承自IEnumerable。而实际上也是如此,我们可以说ICollection比IEnumerable多支持一些功能,不仅仅只提供基本的遍历功能,还包括:
-
统计集合和元素个数
-
获取元素的下标
-
判断是否存在
-
添加元素到未尾
-
移除元素等等。。。
ICollection 与ICollection
IList和IList
IList则是直接继承自ICollection和IEnumerable。所以它包括两者的功能,并且支持根据下标访问和添加元素。IndexOf, Insert, RemoveAt等等。我们可以这样说,IEnumerable支持的功能最少,只有遍历。而ICollection支持的功能稍微多一点,不仅有遍历还有维护这个集合的功能。而IList是最全的版本。
IReadOnlyList
这个是在Framework4.5中新增的接口类型,可以被看作是IList
IDictionary
IDictionary提供了对键值对集合的访问,也是继承了ICollection
关联性泛型集合类
关联性集合类即我们常说的键值对集合,允许我们通过Key来访问和维护集合。我们先来看一下 FCL为我们提供了哪些泛型的关联性集合类:
-
Dictionary
-
SortedDictionary
-
SortedList
Dictionary
Dictionary
Dictionary
作为TKey的类型必须实现GetHashCode()和Equals() 或者提供一个IEqualityComparer,否则操作可能会出现问题。
SortedDictioanry
SortedDictionary
SortedList
SortedList
非关联性泛型集合类
非关联性集合就是不用key操作的一些集合类,通常我们可以用元素本身或者下标来操作。FCL主要为我们提供了以下几种非关联性的泛型集合类。
-
List
-
LinkedList
-
HashSet
-
SortedSet
-
Stack
-
Queue
List
泛型的List 类提供了不限制长度的集合类型,List在内部维护了一定长度的数组(默认初始长度是4),当我们插入元素的长度超过4或者初始长度 的时候,会去重新创建一个新的数组,这个新数组的长度是初始长度的2倍(不永远是2倍,当发现不断的要扩充的时候,倍数会变大),然后把原来的数组拷贝过来。所以如果知道我们将要用这个集合装多少个元素的话,可以在创建的时候指定初始值,这样就避免了重复的创建新数组和拷贝值。
另外的话由于内部实质是一个数组,所以在List的未必添加数据是比较快的,但是如果在数据的头或者中间添加删除数据相对来说更低效一些因为会影响其它数据的重新排列。
LinkedList
LinkedList在内部维护了一个双向的链表,也就是说我们在LinkedList的任何位置添加或者删除数据其性能都是很快的。因为它不会导致其它元素的移动。一般情况下List已经够我们使用了,但是如果对这个集合在中间的添加删除操作非常频繁的话,就建议使用LinkedList。
HashSet
HashSet是一个无序的能够保持唯一性的集合。我们也可以把HashSet看作是Dictionary
HashSet不支持下标访问。
SortedSet
SortedSet和HashSet,就像SortedDictionary和Dictionary一样,还记得这两个的区别么?SortedSet内部也是一个二叉树,用来支持按顺序的排列元素。
Stack
后进先出的队列
不支持按下标访问
Queu
先进先出的队列
不支持按下标访问
线程安全的集合类
-
ConcurrentQueue 线程安全版本的Queue
-
ConcurrentStack线程安全版本的Stack
-
ConcurrentBag线程安全的对象集合
-
ConcurrentDictionary线程安全的Dictionary
-
BlockingCollection
.NET为我们提供的集合类是我们很常用的工具类之一,希望这篇文章能够帮助大家更好的认识这些集合类。当然,个人感觉还有不完善的地方,比如说HashTable和Binary Search Tree就没有细究下去,包括单向链表和双向链表之间的对比本文也没有提及。感兴趣的朋友可以深入了解一下。