c# 集合类
来源:互联网 发布:魔兽淘宝代练等级 编辑:程序博客网 时间:2024/06/16 21:09
c#关于集合类分别哟两个命名空间:
System.Collections 命名空间 定义各种对象(如列表、队列、位数组、哈希表和字典)的集合
System.Collections.Generic 命名空间 定义泛型集合的接口和类
两种的区别就像是ArrayList和List的区别
通常情况下,建议您使用泛型集合,因为这样可以获得类型安全的直接优点而不需要从基集合类型派生并实现类型特定的成员。此外,如果集合元素为值类型,泛型集合类型的性能通常优于对应的非泛型集合类型(并优于从非泛型基集合类型派生的类型),因为使用泛型时不必对元素进行装箱。
下面的泛型类型对应于现有的集合类型:
- List 是对应于 ArrayList 的泛型类。
- Dictionary 是对应于 Hashtable 的泛型类。
- Collection 是对应于 CollectionBase 的泛型类。Collection 可以用作基类,但是与CollectionBase 不同的是它不是抽象的,因而更易于使用。
- ReadOnlyCollection 是对应于 ReadOnlyCollectionBase 的泛型类。ReadOnlyCollection 不是抽象的,它具有一个构造函数,该构造函数使其更易于将现有的 List 公开为只读集合。
- Queue、Stack 和 SortedList 泛型类分别对应于与其同名的非泛型类。
有几种泛型集合类型没有对应的非泛型类型:
- LinkedList 是一个通用链接列表,它提供运算复杂度为 O(1) 的插入和移除操作。
- SortedDictionary 是一个排序的字典,其插入和检索操作的运算复杂度为 O(log n),这使得它成为 SortedList 的十分有用的替代类型。
- KeyedCollection 是介于列表和字典之间的混合类型,它提供了一种存储包含自己键的对象的方法。
C#集体类型( Collections in C#)
集合是.NET FCL(Framework Class Library)中很重要的一部分,也是我们开发当中最常用到的功能之一,几乎是无处不在。俗话说知其然,知其所以然,平常看到IEnumerable,IEnumerator,ICollection是不是知道他们之间各自的区别?除了List和Dictionary以外,你还用过哪些其它的集合类?废话少说,今天我们就来看一些这些定义集合类的接口以及他们的实现。
- 集合接口
- 关联性泛型集合类
- 非关联性泛型集合类
- 推荐使用场景
- 非泛型集合类
- 线程安全集合类
集合接口
先来看一下,FCL为我们提供了哪些接口:
IEnumerable 和IEnumberator
public
interface
IEnumerator
{
bool
MoveNext();
object
Current {
get
; }
void
Reset();
}
IEnumerator定义了我们遍历集合的基本方法,以便我们可以实现单向向前的访问集合中的每一个元素。而IEnumerable只有一个方法GetEnumerator即得到遍历器。
public
interface
IEnumerable
{
IEnumerator GetEnumerator();
}
注意:我们经常用的foreach即是一种语法糖,实际上还是调用Enumerator里面的Current和MoveNext实现的遍历功能。
List<
string
> list =
new
List<
string
>()
{
"Jesse"
,
"Chloe"
,
"Lei"
,
"Jim"
,
"XiaoJun"
};
// Iterate the list by using foreach
foreach
(
var
buddy
in
list)
{
Console.WriteLine(buddy);
}
// Iterate the list by using enumerator
List<
string
>.Enumerator enumerator = list.GetEnumerator();
while
(enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
上面的代码中用到的foreach和enumerator到IL中最后都会被翻译成enumerator的MoveNext和Current。
IEnumerable是一个很有用的接口,实现它的好处包括:
- 支持foreach语句
- 作为一个标准的集合类与其它类库进行交互
- 满足更复杂的集合接口的需求
- 支持集合初始化器
当然实现的方法也有很多,如下:
- 如果我们集合是通过封装其它集合类而来的,那么我们可以直接返回这个集合的enumerator
- 通过yield return 来返回
- 实现我们自己的IEnumerator来实现
这里给大家演示一下如何通过yield来实现返回enumerator
public
class
BuddyList : IEnumerable
{
private
string
[] data=
new
string
[]
{
"Jesse"
,
"Chloe"
,
"Lei"
,
"Jim"
,
"XiaoJun"
};
public
IEnumerator GetEnumerator()
{
foreach
(
var
str
in
data)
{
yield
return
str;
}
}
}
var
myBuddies=
new
BuddyList();
foreach
(
var
str
in
myBuddies)
{
Console.WriteLine(str);
}
ICollection和ICollection
从最上面第一张图我们可以知道,ICollection是直接继承自IEnumerable。而实际上也是如此,我们可以说ICollection比IEnumerable多支持一些功能,不仅仅只提供基本的遍历功能,还包括:
- 统计集合和元素个数
- 获取元素的下标
- 判断是否存在
- 添加元素到未尾
- 移除元素等等。。。
ICollection 与ICollection 略有不同,ICollection不提供编辑集合的功能,即Add和Remove。包括检查元素是否存在Contains也不支持。
IList和IList
IList则是直接继承自ICollection和IEnumerable。所以它包括两者的功能,并且支持根据下标访问和添加元素。IndexOf, Insert, RemoveAt等等。我们可以这样说,IEnumerable支持的功能最少,只有遍历。而ICollection支持的功能稍微多一点,不仅有遍历还有维护这个集合的功能。而IList是最全的版本。
IReadOnlyList
这个是在Framework4.5中新增的接口类型,可以被看作是IList的缩减版,去掉了所有可能更改这个集合的功能。比如:Add, RemoveAt等等。
IDictionary<TKey,TValue>
IDictionary提供了对键值对集合的访问,也是继承了ICollection和IEnumerable,扩展了通过Key来访问和操作数据的方法。
关联性泛型集合类
关联性集合类即我们常说的键值对集合,允许我们通过Key来访问和维护集合。我们先来看一下 FCL为我们提供了哪些泛型的关联性集合类:
- Dictionary<TKey,TValue>
- SortedDictionary<TKey,TValue>
- SortedList<TKey,TValue>
Dictionary<TKey,TValue>
Dictionary<TKey,TValue>可能是我们最常用的关联性集合了,它的访问,添加,删除数据所花费的时间是所有集合类里面最快的,因为它内部用了Hashtable作为存储结构,所以不管存储了多少键值对,查询/添加/删除所花费的时间都是一样的,它的时间复杂度是O(1)。
Dictionary<TKey,TValue>优势是查找插入速度快,那么什么是它的劣势呢?因为采用Hashtable作为存储结构,就意味着里面的数据是无序排列的,所以想按一定的顺序去遍历Dictionary<TKey,TValue>里面的数据是要费一点工夫的。
作为TKey的类型必须实现GetHashCode()和Equals() 或者提供一个IEqualityComparer,否则操作可能会出现问题。
SortedDictioanry<TKey,TValue>
SortedDictionary<TKey,TValue>和Dictionary<TKey,TValue>大致上是类似的,但是在实现方式上有一点点区别。SortedDictionary<TKey,TValue>用二叉树作为存储结构的。并且按key的顺序排列。那么这样的话SortedDictionary<TKey,TValue>的TKey就必须要实现IComparable。如果想要快速查询的同时又能很好的支持排序的话,那就使用SortedDictionary吧。
SortedList<TKey,TValue>
SortedList<TKey,TValue>是另一个支持排序的关联性集合。但是不同的地方在于,SortedList实际是将数据存存储在数组中的。也就是说添加和移除操作都是线性的,时间复杂度是O(n),因为操作其中的元素可能导致所有的数据移动。但是因为在查找的时候利用了二分搜索,所以查找的性能会好一些,时间复杂度是O(log n)。所以推荐使用场景是这样地:如果你想要快速查找,又想集合按照key的顺序排列,最后这个集合的操作(添加和移除)比较少的话,就是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<TKey,TValue>,只不过TKey和TValue都指向同一个对象。HashSet非常适合在我们需要保持集合内元素唯一性但又不需要按顺序排列的时候。
HashSet不支持下标访问。
SortedSet
SortedSet和HashSet,就像SortedDictionary和Dictionary一样,还记得这两个的区别么?SortedSet内部也是一个二叉树,用来支持按顺序的排列元素。
Stack
后进先出的队列
不支持按下标访问
Queu
先进先出的队列
不支持按下标访问
推荐使用场景
集合顺序排列连顺存储直接访问方式访问时间操作时间备注Dictionary 是KeyKey:
O(1)
O(1)访问性能最快,不支持排序SortedDinctionary顺序排列否KeyKey:
O(log n)O(log n)快速访问和支持排序的折衷SortedList顺序排列是KeyKey:
O(log n)
O(n)和SortedDictionary相似,只是内部用数据替代树作为存储结构。List使用者可以精确控制元素的位置是IndexIndex: O(1)
Value: O(n)
O(n)最适合需要直接访问每一个元素的少量集合。LinkedList使用者可以精确控制元素的位置否不支持Value:
O(n)
O(1)最适合不需要直接访问单个元素,但是在集合中添加/移除非常频繁的场景。HashSet不支持是KeyKey:
O(1)
O(1)能保持元素唯一性的集合。不支持排序SortedSet顺序排列否KeyKey:
O(log n)
O(log n)能保持元素唯一性并且支持排序。StackLIFO是只能获取顶部元素Top: O(1)O(1) QueueFIFO是只能获底部元素Front: O(1)O(1)
- C#集合类
- C# 集合类
- C#集合类选择
- C#集合类
- C#中的集合类
- C#集合类概述
- c#集合类
- C#集合类
- C# 集合类
- C# 集合类总结
- C#集合类
- C#集合类
- C#集合类选择
- C#集合类Queue
- c#集合类总结
- C#中的集合类
- C#集合类
- C#集合类Queue
- cdh 安装完整版
- Gradle--使用gradle构建Android项目的基础知识
- 转载:c++虚函数的作用
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- jenkins error:java.io.IOException: Failed to create a directory at ...
- c# 集合类
- 二叉搜索树后序序列
- 添加事件,兼容浏览器
- 模拟垂直滚动条
- WEBSPHERE性能调优!
- git用.gitignore忽略指定文件
- Customizing Existing Classes
- 初识Curator - instance must be started before calling this method
- Android四大基本组件介绍与生命周期