比较常用集合类如何选择
首先对于功能简单的集合类,对于减少占用资源,减少系统开销来讲是要好于功能较为强大的集合类的。功能强大的集合处理的时候必然要占用更多的系统内存资源,这是显而易见的。那么在考虑如何选择集合的时候就要从功能和性能两个方面考虑,看看更注重哪一方面是性能还是功能。下面具体分析一下常用集合的性能与功能方面的问题。
- Array在创建的时候要声明数组的大小。向数组种添加元素的时间复杂度为O(1)。取得数组中元素的时间复杂度为O(1)。考虑使用数组的时候要注意它的大小是固定的,需要在声明是给出数组的大小,不可以动态的改变。对于处理元素个数不定的情况下,并不适用,既有可能造成资源的浪费又有可能导致分配空间不足,使程序无法正常运行出现异常。但如果处理固定数量的元素的情况下用数组效率使较高的,因为它的存取数据的时间复杂度都为O(1),是最佳的情况,访问速度快,不耗费额外的资源。
- ArrayList在创建的时候不需要声明大小,可以动态的改变大小。但它有一个Capacity值,作为ArrayList的初始容量。当所加入的元素数量不超过这个值的时候,向ArrayList中加入元素的时间复杂度为O(1),如果元素的数量超过了这个值,那么向ArrayList中加入元素的时间复杂度为O(n)。对ArrayList进行排序,它的时间复杂度为O(n log n),最坏的情况下它的时间复杂度为O(n^2)。检索ArrayList中的元素的时间复杂度为O(1),修改ArrayList中的元素的值的时间复杂度也为O(1)。ArrayList功能更为完善,但同时性能也作为牺牲的代价。
- HashTable也可以动态的改变大小。它是通过键值对来进行访问的。对于向HashTable中添加元素,如果当前HashTable中的元素数小于HashTable的容量,则添加元素的运算复杂度为O(1),如果需要增加容量以容纳新元素,则添加元素变成O(n),其中n为HashTable中元素的个数。对于检索和修改元素值的时间复杂度HashTable为O(1),是比较高效的。Sortedlist与HashTable不同,SortedList按键排序并可按照键和索引访问。
- 加入元素:对于未排序的数据,此方法的运算复杂度为 O(n),其中 n 是 Count。如果在列表末尾添加了新元素,则此方法的运算复杂度为 O(log n)。如果插入操作导致大小调整,则运算复杂度为 O(n)。检索元素:检索此属性的值的运算复杂度为 O(log n),其中 n 是 Count。如果 SortedList 中已存在键,则设置此属性的运算复杂度为 O(log n)。如果键不存在于列表中,则对于未排序的数据,设置此属性的运算复杂度为 O(n),如果在列表末尾添加了新元素,则设置此属性的运算复杂度为 O(log n)。如果插入操作导致大小调整,则运算复杂度为 O(n)。由于SortedList加了索引,相对HashTable来讲必然要多耗费资源,性能降低,但功能更为强大。
- 对于Queue和Stack都具有自己独特的特性,一个是先进先出,一个是后进先出,对于这两个集合类的使用应该容易区别,根据其特点在特定的情况下使用。而对于上面提到的几个集合类,它们有自己对应的泛型集合。泛型集合是通用的集合,可以存放各种类型的数据,包括对象和各种基本数据类型,因为在C#中所有的类都是由Object继承而来,非泛型集合所接受的参数是Object类型的,这就导致了它可以存储各种类型的数据。这个特点在某些情况下是它的优势,比如用户需要维护一组不同类型的数据的时候。但它也优它的弊端,就是在进行读写数据的时候都需要一个装箱与拆箱的过程,这个过程是比较消耗资源的。同时这样也存在着类型安全问题,并不能保证用户转换的类型是正确的,可能会导致程序无法正常运行。对于这样的问题,泛型集合对其做了很好的弥补。泛型集合会在声明集合时指定一种类型作为集合存储的类型,不可以存放其他类型的数据。这就避免了数据类型间的转换,避免了反复的拆箱与装箱,提高了性能。