关于.NET的集合总结

集合是一些有共同特征的独立数据项组成的,通过集合,我们可以可以使用相同的调用代码来处理一个集合的所有元素,而不用单独处理每一个单独的项。.net的集合诸如(System.Array类以及 System.Collections命名空间)数组、列表、队列、堆栈、哈希表、字典甚至(System.Data下)DataSet、DataTable,还有2.0中加入的集合的泛型版本(System.Collections.Generic和 System.Collections.ObjectModel),4.0中引入的有效线程安全操作的集合(System.Collections.Concurrent)。

面对这么多的集合,你了解各个集合有哪些优势,在一个特定的场景中使用哪个集合吗?本文试图探讨一下这个问题,泛泛而谈,不涉及深入的内存数据结构的追究,希望能给大家带来一些益处。

集合接口
        在分别讨论各种集合之前,我们先讨论一下集合的共性,整个集合体系的继承层次。

ICollection 接口是 System.Collections 命名空间中类的基接口,而相应的ICollection<T>是所有泛型版本集合的基接口。所有的的集合类都直接或间接的继承他们。

ICollection又继承IEnumerable,来提供方便的枚举功能,不过更值得注意ICollection提供同步访问的线程安全性控制:

IsSynchronized:获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。


        SyncRoot:获取可用于同步对 ICollection 的访问的对象。

例如,我们可以通过以下来对集合进行线程安全访问,不过有些集合提供Synchronized方法来提供线程安全集合的封装。

复制代码 代码如下:


ICollection myCollection = someCollection;
lock(myCollection.SyncRoot)
{
       // Insert your code here.
}


       不过默认情况下集合不是线程安全的。如果需要对集合进行可伸缩的且高效的多线程访问,请使用System.Collections.Concurrent命名空间中的某个类。      

而与非泛型版本不同的是,泛型版本的集合除了实现了泛型的接口外,也实现了非泛型的相应的接口。如ICollection<T>实现了IEnumerable和IEnumerable<T>,但是泛型集合却没有提供同步访问的线程安全控制,也就是说泛型集合的同步访问,我们必须自己去处理同步或使用System.Collections.Concurrent命名空间中的某个类。

另外,IList和IDictionary分别继承自ICollection,IList的实现者(如Array、ArrayList 或 List<T>等)和ICollection的实现者(例如 Queue、ConcurrentQueue<T>、Stack、 ConcurrentStack<T>或 LinkedList<T>)的每个元素都是一个值,而IDictionary的实现者(例如 Hashtable 和 SortedList 类、Dictionary<TKey, TValue> 和 SortedList<TKey, TValue> 泛型类)每个元素都是一个键值对。

接下来,我们将分别讨论和比较下一些常用的集合。

数组Array
        Array不是System.Collections的一部分,但是它继承自IList接口。.net的Array可以有多维数组、交错数组,甚至创建下限不是0是数组,默认情况下推荐使用下限是0的一维数组,这常用的数组是经过优化的,性能最高。

与System.Collections集合不同的是,Array具有固定的容量,若要增加容量,您必须创建具有所需容量的新 Array 对象,将旧 Array 对象中的元素复制到新对象中,然后删除该旧 Array。而System.Collections下的集合在达到当前容量时可自动扩充容量:内存被重新分配,元素从旧集合复制到新集合中。 这减少了使用集合所需的代码,但是,集合的性能可能仍受到消极影响。 因此我们应将初始容量设置为集合的估计的大小以避免因多次重新分配导致的不佳性能。

System.Collections下的集合类
        该类型的集合都具有排序功能且大多数经过了索引。能自动处理内存管理,容量按需扩大。

ArrayList和List<T>:List<T>是ArrayList的泛型版本,它们和Array一样都是基于索引访问,每个数据项只保存一个数据值,但是它们提供比Array更强大的功能和操作,使得它们也更容易使用。性能方面,泛型版本总是比非泛型更优先采用,除非成员类型是object类型,因为泛型版本免除了装箱和拆箱的操作;在不需要重新分配集合容量的情况下,List<T>的性能与同类型的数组十分相近。另外,ArrayList可以很方便的创建同步版本,但Array和List<T>的同步工作必须有自己完成。

Hashtable 和 Dictionary 集合类型:这些集合每个项是一个键值对。Dictionary<Tkey,Tvalue>是Hashtable的泛型版本。Hashtable对象是由包含集合元素的存储桶组成的,每个存储桶与使用元素键基于哈希函数生成的一个哈希码关联,包含多个元素。因此这类集合比其它的大多数集合在搜索和检索数据上更快捷。而同样的Dictionary<Tkey,Tvalue>总是比Hashtable性能更好,因此推荐使用,多线程同步使用ConcurrentDictionary<TKey, TValue>类。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjgxfz.html