以下是对最长用的集合进行简单的总结
集合 | 说明 |
---|---|
List |
可以像数组一样按索引访问列表,但提供了其他方法来搜索和排序 |
Queue |
先入先出数据结构,提供了方法将数据项添加到队列的一段,从另一端删除项,以及只检查不删除 |
Stack |
先入后出数据结构,提供了方法将数据压入栈顶,从栈顶出栈,以及只检查栈顶的项而不删除 |
LinkedList |
双向有序列表,为任何一端的插入和删除进行了优化,这种集合既可作为队列,也可作为栈,还支持列表那样的随机访问 |
HashSet |
无序值列表,为快速数据获取而优化,提供了面向集合的方法来判断它容纳的项是不是另一个HashSet 对象中的项的子集,以及计算不同HashSet 对象的交集和并集 |
Dictionary |
字典集合允许根据键而不是索引来获取值 |
SortedList |
键/值对的有序列表,键必须实现Icomparable 接口 |
先来了解下集合的基本信息:
1、BCL中集合类型分为泛型集合与非泛型集合。
2、非泛型集合的类和接口位于System.Collections命名空间。
3、泛型集合的类和接口位于System.Collections.Generic命名空间。
ICollection接口是System.Collections命名空间中非泛型集合类的基接口,它继承自IEnumerable接口,从IEnumerable接口继承意味着实现该接口的实现类需要实现一个枚举器方法:GetEnumerator,该方法返回IEnumerator类型的数据。IDictionary和IList接口继承自ICollection作为更为专用的接口,其中IDictionary接口是键/值对接口,它的实现如HashTable类;而IList是值的集合,其成员可通过索引访问,如ArrayList类,次类集合与数组相比,可以认为是可变的集合,优点有,长度自动增长等。IEnumerable和IEnumerable是所有集合或集合接口的基接口,所有集合接口或集合都继承、实现了它。其中IEnumerable是最底层的接口。在非泛型集合里存放的都是System.Object类型。
一、下面列出非泛型和泛型集合的接口
非泛型集合接口 | 泛型集合接口 | 说明 |
---|---|---|
ICollection |
ICollection |
定义所有集合的大小(Count),枚举器(foreach)和同步(copyto)方法,继承自IEnumerable |
IList |
IList |
表示可按照索引单独访问的一组对象(像数组一样) |
IDictionary |
IDictionary |
表示键/值对的集合 |
IComparer |
IComparer |
定义类型为比较两个对象而实现的方法 |
IEqualityComparer |
IEqualityComparer |
定义方法以支持对象的相等比较 |
IEnumerable |
IEnumerable |
公开枚举器。实现了该接口意味着允许foreach语句循环访问集合中的元素 |
IEnumerator |
IEnumerator |
支持在泛型集合上进行简单迭代 |
下面来详细介绍各种集合接口和集合。个人认为应该从根底说起。
先抱着MSDN来说IEnumerable,扩展方法就不说了,扩展方法跳过,留到学Linq的时候再说。
1.IEnumerable接口就一个方法,没有属性
方法 | 说明 |
---|---|
GetEnumerator | 返回一个循环访问集合的枚举数。 实现或继承了该接口,就是为了这个方法,可以foreach遍历 |
2、IEnumerable
接口也一样,也是就一个方法,没有属性。
方法 | 说明 |
---|---|
GetEnumerator | 返回一个循环访问集合的枚举数。 |
3、ICollection接口
方法 | 说明 |
---|---|
CopyTo | 从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。 |
GetEnumerator | 返回一个循环访问集合的枚举数。 (继承自 IEnumerable。) |
属性 | |
Count | 获取 ICollection 中包含的元素数。 原来Count的源头在这里。 |
IsSynchronized | 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 |
SyncRoot | 获取可用于同步 ICollection 访问的对象。 |
4、ICollection
方法 | 说明 |
---|---|
Count | 获取 ICollection 中包含的元素数。 |
IsReadOnly | 获取一个值,该值指示 ICollection 是否为只读。 |
属性 | |
Add | 将某项添加到 ICollection 中。 |
Clear | 从 ICollection 中移除所有项。 |
Contains | 确定 ICollection 是否包含特定值。 |
CopyTo | 从特定的 Array 索引开始,将 ICollection 的元素复制到一个 Array 中。 |
GetEnumerator | 已重载。 |
Remove | 从 ICollection 中移除特定对象的第一个匹配项。 |
这个ICollect ,才开始有点集合的影子了,可以Add、Clear了,怪不得它作为泛型集合接口的基类。 |
5、IList
IList继承了ICollection和IEnumerable
方法 | 说明 |
---|---|
Add | 将某项添加到 IList 中。 |
Clear | 从 IList 中移除所有项。 |
Contains | 确定 IList 是否包含特定值。 |
CopyTo | 从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。(继承自 ICollection。) |
GetEnumerator | 返回一个循环访问集合的枚举数。 (继承自 IEnumerable。) |
IndexOf | 确定 IList 中特定项的索引。 |
Insert | 将一个项插入指定索引处的 IList。 |
Remove | 从 IList 中移除特定对象的第一个匹配项。 |
RemoveAt | 移除指定索引处的 IList 项。 |
属性 | |
Count | 获取 ICollection 中包含的元素数。 (继承自 ICollection。) |
IsFixedSize | 获取一个值,该值指示 IList 是否具有固定大小。 |
IsReadOnly | 获取一个值,该值指示 IList 是否为只读。 |
IsSynchronized | 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 (继承自 ICollection。) |
Item | 获取或设置指定索引处的元素。 |
SyncRoot | 获取可用于同步 ICollection 访问的对象。 (继承自 ICollection。) |
可以看到,在不断的继承过程中,这些接口不断地添加自己的东西,越继承越多,越继承越多 |
6、IList
IList
继承了ICollection
,IEnumerable
,IEnumerable
方法 | 说明 |
---|---|
Add | 将某项添加到 ICollection<(Of <(T>)>) 中。 (继承自 ICollection<(Of <(T>)>)。) |
Clear | 从 ICollection<(Of <(T>)>) 中移除所有项。 (继承自 ICollection<(Of <(T>)>)。) |
Contains | 确定 ICollection<(Of <(T>)>) 是否包含特定值。 (继承自 ICollection<(Of <(T>)>)。) |
CopyTo | 从特定的 Array 索引开始,将 ICollection<(Of <(T>)>) 的元素复制到一个 Array 中。 (继承自 ICollection<(Of <(T>)>)。) |
GetEnumerator | 已重载。 |
IndexOf | 确定 IList<(Of <(T>)>) 中特定项的索引。 |
Insert | 将一个项插入指定索引处的 IList<(Of <(T>)>)。 |
Remove | 从 ICollection<(Of <(T>)>) 中移除特定对象的第一个匹配项。 (继承自 ICollection<(Of <(T>)>)。) |
RemoveAt | 移除指定索引处的 IList<(Of <(T>)>) 项。 |
属性 | |
Count | 获取 ICollection<(Of <(T>)>) 中包含的元素数。 (继承自 ICollection<(Of <(T>)>)。) |
IsReadOnly | 获取一个值,该值指示 ICollection<(Of <(T>)>) 是否为只读。 (继承自 ICollection<(Of <(T>)>)) |
Item | 获取或设置指定索引处的元素。 |
同样,在不断的继承中,增加了新的东西,功能也越来越强大,支持索引获取和设置就是IList这个源头的。一直弄不明白,NHibernate为什么会选择这个接口来返回数据,其实这个接口的东西够用了。 |
7、IDictionary
接口 IDictionary
是最底层出现的键/值对集合了,相当于值集合中的ICollection
方法 | 说明 |
---|---|
Add | 已重载。 |
Clear | 从 ICollection<(Of <(T>)>) 中移除所有项。 (继承自 ICollection<(Of <(T>)>)。) |
Contains | 确定 ICollection<(Of <(T>)>) 是否包含特定值。 (继承自 ICollection<(Of <(T>)>)。) |
ContainsKey | 确定 IDictionary<(Of <(TKey, TValue>)>) 是否包含具有指定键的元素。 |
CopyTo | 从特定的 Array 索引开始,将 ICollection<(Of <(T>)>) 的元素复制到一个 Array 中。 (继承自 ICollection<(Of <(T>)>)。) |
GetEnumerator | 已重载。 |
Remove | 已重载。 |
TryGetValue | 获取与指定的键相关联的值。 |
属性 | |
Count | 获取 ICollection<(Of <(T>)>) 中包含的元素数。 (继承自 ICollection<(Of <(T>)>)。) |
IsReadOnly | 获取一个值,该值指示 ICollection<(Of <(T>)>) 是否为只读。 (继承自 ICollection<(Of <(T>)>)。) |
Item | 获取或设置具有指定键的元素。 |
Keys | 获取包含 IDictionary<(Of <(TKey, TValue>)>) 的键的 ICollection<(Of <(T>)>)。 |
Values | 获取包含 IDictionary<(Of <(TKey, TValue>)>) 中的值的 ICollection<(Of <(T>)>)。 |
该接口提供的功能和ICollection差不多,其实就是键/值对的开宗立派者。 |
8、IDictionary
方法 | 说明 |
---|---|
Add | 在 IDictionary 对象中添加一个带有所提供的键和值的元素。 |
Clear | 从 IDictionary 对象中移除所有元素。 |
Contains | 确定 IDictionary 对象是否包含具有指定键的元素。 |
CopyTo | 从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。 (继承自 ICollection。) |
GetEnumerator | 已重载。 |
Remove | 从 IDictionary 对象中移除带有指定键的元素。 |
属性 | |
Count | 获取 ICollection 中包含的元素数。 (继承自 ICollection。) |
IsFixedSize | 获取一个值,该值指示 IDictionary 对象是否具有固定大小。 |
IsReadOnly | 获取一个值,该值指示 IDictionary 对象是否为只读。 |
IsSynchronized | 获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 (继承自 ICollection。) |
Item | 获取或设置具有指定键的元素。 |
Keys | 获取 ICollection 对象,它包含 IDictionary 对象的键。 |
SyncRoot | 获取可用于同步 ICollection 访问的对象。 (继承自 ICollection。) |
Values | 获取 ICollection 对象,它包含 IDictionary 对象中的值。 |
9、ISet
Set
同样是继承自ICollection
,IEnumerable
,IEnumerable
方法 | 说明 |
---|---|
Add(T) | 将某项添加到 ICollection 中。 (继承自 ICollection。) |
Add(T) | 向当前集内添加元素,并返回一个指示是否已成功添加元素的值。 |
Clear | 从 ICollection 中移除所有项。 (继承自 ICollection。) |
Contains | 确定 ICollection 是否包含特定值。 (继承自 ICollection。) |
CopyTo | 从特定的 Array 索引开始,将 ICollection 的元素复制到一个 Array 中。 (继承自 ICollection。) |
ExceptWith | 从当前集内移除指定集合中的所有元素。 |
GetEnumerator() | 返回一个循环访问集合的枚举数。 (继承自 IEnumerable。) |
GetEnumerator() | 返回一个循环访问集合的枚举器。 (继承自 IEnumerable。) |
IntersectWith | 修改当前集,使该集仅包含指定集合中也存在的元素。 |
IsProperSubsetOf | 确定当前的设置是否正确 (严格) 指定集合的子集。 |
IsProperSupersetOf | 确定当前的设置是否正确 (严格) 指定集合中的超集。 |
IsSubsetOf | 确定一个集是否为指定集合的子集。 |
IsSupersetOf | 确定当前集是否为指定集合的超集。 |
Overlaps | 确定当前集是否与指定的集合重叠。 |
Remove | 从 ICollection 中移除特定对象的第一个匹配项。 (继承自 ICollection。) |
SetEquals | 确定当前集与指定的集合中是否包含相同的元素。 |
SymmetricExceptWith | 修改当前集,使该集仅包含当前集或指定集合中存在的元素(但不可包含两者共有的元素)。 |
UnionWith | 修改当前设置,以使其包含当前集或指定的集合中的所有元素。 |
先说IComparer接口,这个接口就一个方法,用于如何比较两个对象
public class StringLengthComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
if (s1.Length > s2.Length)
{
return (1);
}
else if (s1.Length < s2.Length)
{
return (2);
}
else
{
return (0);
}
}
}
说完了集合接口,现在开始说集合。
1、ArrayList
ArrayList实现了IList、ICollection、IEnumerable接口。
ArrayList与Array的名字很相似,现在来比较一下两者的异同。
相同点:
(1)、两者都实现了IList、ICollection、IEnumerable接口。
(2)、两者都可以使用整数索引访问集合中的元素,包括读取和赋值,且集合中的索引都从0开始。
不同点:
(1)、ArrayList是集合,而Array是数组。
(2)、ArrayList是具体类,Array是抽象类。
(3)、数组必须在实例化时指定元素的数量,该数量一旦确定就不可以更改了,而ArrayList扩展了这一点,当实例化一个ArrayList实例时可以不指定集合元素数(有默认初始容量),当然你也可以指定初始容量。
(4)、获取数组的元素数时使用Length属性,而获取ArrayList集合的元素数时使用Count属性。
(5)、数组可以有多维,而ArrayList只能是一维。
来看ArrayList具体提供的功能
集合-ArrayList的用法
属性 | 说明 |
---|---|
Capacity | 获取或设置 ArrayList 可包含的元素数。 |
Count | 获取 ArrayList 中实际包含的元素数。 |
IsFixedSize | 获取一个值,该值指示 ArrayList 是否具有固定大小。 |
IsReadOnly | 获取一个值,该值指示 ArrayList 是否为只读。 |
IsSynchronized | 获取一个值,该值指示是否同步对 ArrayList 的访问(线程安全)。 |
Item | 获取或设置指定索引处的元素。 |
SyncRoot | 获取可用于同步 ArrayList 访问的对象。 |
方法 | |
Adapter | 为特定的 IList 创建 ArrayList 包装。 |
Add | 将对象添加到 ArrayList 的结尾处。 |
AddRange | 将 ICollection 的元素添加到 ArrayList 的末尾。 |
BinarySearch | 已重载。 使用对分检索算法在已排序的 ArrayList 或它的一部分中查找特定元素。 |
Clear | 从 ArrayList 中移除所有元素。 |
Clone | 创建 ArrayList 的浅表副本。 |
Contains | 确定某元素是否在 ArrayList 中。 |
CopyTo | 已重载。 将 ArrayList 或它的一部分复制到一维数组中。 |
FixedSize | 已重载。 返回具有固定大小的列表包装,其中的元素允许修改,但不允许添加或移除。 |
GetEnumerator | 已重载。 返回循环访问 ArrayList 的枚举数。 |
GetRange | 返回 ArrayList,它表示源 ArrayList 中元素的子集。 |
IndexOf | 已重载。 返回 ArrayList 或它的一部分中某个值的第一个匹配项的从零开始的索引。 |
Insert | 将元素插入 ArrayList 的指定索引处。 可在任意位置插入。 |
InsertRange | 将集合中的某个元素插入 ArrayList 的指定索引处。 |
LastIndexOf | 已重载。 返回 ArrayList 或它的一部分中某个值的最后一个匹配项的从零开始的索引。 |
ReadOnly | 已重载。 返回只读的列表包装。 |
Remove | 从 ArrayList 中移除特定对象的第一个匹配项。 |
RemoveAt | 移除 ArrayList 的指定索引处的元素。 |
RemoveRange | 从 ArrayList 中移除一定范围的元素。 |
Repeat | 返回 ArrayList,它的元素是指定值的副本。 |
Reverse | 已重载。 将 ArrayList 或它的一部分中元素的顺序反转。 |
SetRange | 将集合中的元素复制到 ArrayList 中一定范围的元素上。 |
Sort | 已重载。 对 ArrayList 或它的一部分中的元素进行排序。 |
Synchronized | 已重载。 返回同步的(线程安全)列表包装。 |
ToArray | 已重载。 将 ArrayList 的元素复制到新数组中。 |
TrimToSize | 将容量设置为 ArrayList 中元素的实际数目。 |
static void Main(string[] args)
{
ArrayList arrayList = new ArrayList();
arrayList.Add(1); //Add方法,将一个元素添加到ArrayList中
arrayList.Add("你好");
arrayList.Add(3.265);
IList iList = arrayList;
ICollection iCollection = iList;
IEnumerable iEnumerable = iCollection; //体现了ArrayList的继承关系
foreach (object obj in iEnumerable)
{
Console.WriteLine(obj.ToString());
}
bool b = arrayList.Contains("你好"); //确定ArrayList中是否包含某元素
Console.WriteLine(b); //输出 True
object[] objArr = new object[arrayList.Count + 1];
objArr[0] = "我是用来占位的";
arrayList.CopyTo(objArr, 1); //便宜一位,也就是接受数组从1开始,默认是0
foreach (object obj in objArr)
{
Console.Write(obj.ToString() + "-"); //输出 我是用来占位的-1-你好-3.265-
}
Console.WriteLine();
ArrayList AL = ArrayList.FixedSize(arrayList); //静态方法 返回一个固定大小的ArrayList对象,数量不许改变。也就是说不能添加和删除。
Console.WriteLine(AL.IsFixedSize); //输出True
//AL.Add(111); 此处报异常,"集合的大小是固定的"
ArrayList ALReadOnly = ArrayList.ReadOnly(arrayList);
Console.WriteLine(ALReadOnly.IsReadOnly); //输出True
ArrayList AL1 = arrayList.GetRange(1, 2); //按照索引顺序截取出子集
foreach (object obj in AL1)
{
Console.Write(obj.ToString()); //输出 你好3.265 可以截取出的新ArrayList只包含1,2位
}
Console.WriteLine();
int indexLocation = arrayList.IndexOf(1); //从左边开始检索,返回第一个匹配到的元素的顺序
Console.WriteLine(indexLocation); //输出 0
arrayList.Add(1); //为了体现LastIndexOf的不同,先添加一个1
int lastLocation = arrayList.LastIndexOf(1);
Console.WriteLine(lastLocation); //返回3
arrayList.Insert(2, "Insert插入的元素"); //这个方法与Add的不同在于它可以在任意位置插入
foreach (object obj in arrayList)
{
Console.Write(obj.ToString() + " "); //输出 1 你好 Insert插入的元素 3.265 1
}
ArrayList arr = new ArrayList();
arr.Add(1);
arr.Add(2);
arrayList.AddRange(arr);
foreach (object obj in arrayList)
{
Console.Write(obj.ToString() + "-"); //输出 1 你好 Insert插入的元素 3.265 1 1 2可以看到将一个新的集合追加到了最后
}
arrayList.Remove(2);
foreach (object obj in arrayList)
{
Console.Write(obj.ToString() + "-"); //输出 1 你好 Insert插入的元素 3.265 1 1 可以看到2已经被移除了
}
Console.WriteLine();
arrayList.RemoveAt(0);
foreach (object obj in arrayList)
{
Console.Write(obj.ToString() + "-"); //输出 你好 Insert插入的元素 3.265 1 1 可以看到第0个元素"2"已经被移除了
}
Console.WriteLine();
//arrayList.Reverse();
//foreach (object obj in arrayList)
//{
// Console.Write(obj.ToString() + "-"); //输出顺序倒转的所有元素
//}
ArrayList AL3 = new ArrayList();
arrayList.SetRange(0,AL3); //从第0位开始,将元素复制到AL3中
foreach (object obj in AL3)
{
Console.Write(obj.ToString() + "-"); //输出 你好 Insert插入的元素 3.265 1 1
}
object[] objArrs = new object[arrayList.Count];
objArrs = arrayList.ToArray();
foreach (object obj in objArrs)
{
Console.Write(obj.ToString() + "-");
}
Console.WriteLine();
arrayList.Capacity = 5; //读取或设置可包含元素的数量,如果小于当前会报错。
Console.WriteLine(arrayList.Count); //输出5
arrayList.TrimToSize();
Console.WriteLine(arrayList.Count); //输出5
Console.ReadKey();
}
2、非泛型集合HashTable
Hashtable实现了IDictionary、ICollection以及IEnumerable接口。注意Hashtable,t是小写的。由于是非泛型集合,因此存储进去的都是object类型,不管是键还是值。
Hashtable的要点。
(1)、Hashtable仅有非泛型版本。
(2)、Hashtable类中的键不允许重复,但值可以。
(3)、Hashtable类所存储的键值对中,值可以为null,但键不允许为null。
(4)、Hashtable不允许排序操作。
以下给出一个实例,Hashtable提供的功能是在于ArraryList差不多,只不过存储的是键值对而已。只写个基本短小的示例。
C#中HashTable的用法
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add(1,1);
ht.Add("我爱你","是吗?");
Console.WriteLine(ht.Count); //输出 2
Console.WriteLine(ht["我爱你"]); //输出 "是吗?" 用键 获取值
Console.WriteLine(ht.Contains(1)); //输出True
Console.ReadKey();
}
3、Queue
和Queue
Queue成为队列,队列是这样一种数据结构,数据有列表的一端插入,并由列表的另一端移除。就像单行道,只能从一段进,从一端出。Queue类实现了ICollection和IEnumerable接口。
Queue的一些重要特性。
1、先进先出
2、可以添加null值到集合中
3、允许集合中的元素重复
4、Queue容量会按需自动添加
5、Queue的等比因子是当需要更大容量时当前容量要乘以的数字,默认是2.0。
成员 | 类型 | 说明 |
---|---|---|
Clear | 方法 | 从Queue中移除所有对象,清空队列。 |
Contains | 方法 | 确定某元素是否在Queue中 |
Enqueue | 方法 | 将对象添加到Queue的结尾处入列 |
Dequeue | 方法 | 移除并返回位于Queue开始处的对象出列 |
Peek | 方法 | 返回位于Queue开始出的对象,但不将其移除,与出列不同,出列是会移除的 |
提供的功能都是差不多的,现在给出一个实例,主要显示Queue的作用:
static void Main(string[] args)
{
Queue q = new Queue();
q.Enqueue(1);
q.Enqueue("想家了!");
q.Enqueue(1.23);
Console.WriteLine(q.Peek()); //输出1 获取值但不移除,与出列不同
int Count = q.Count; //出队的时候q.Count在变化,因此q.Count放在循环条件里是不妥的
for (int i = 0; i < Count; i++)
{
Console.WriteLine(q.Dequeue().ToString()); //注意 输出 1 想家了 1.23 都是从最先添加的先拿
}
Console.WriteLine(q.Count); //输出0 出列一次,就自动移除了。
Queue qInt = new Queue();
qInt.Enqueue(1);
qInt.Enqueue(2);
qInt.Enqueue(3);
Console.WriteLine(qInt.Peek()); //输出1
int IntCount = qInt.Count;
for (int i = 0; i < IntCount; i++)
{
Console.WriteLine(qInt.Dequeue()); //注意 输出 123 都是从最先添加的先拿
}
Console.WriteLine(q.Count); //输出0 出列一次,就自动移除了。
Console.ReadKey();
}
4、Stack和Stack
Stack称为栈,栈和队列非常相似,只不过队列是先进先出,而栈中的数据添加和移除都在一端进行,遵守栈中的数据则后进先出。Stack类实现了ICollection和IEnumerable接口。
Stack类的一些重要特性如下:
1、后进先出。
2、可以添加null值到集合中。
3、允许集合中的元素重复。
4、Stack的容量会按需自动增加。
列出几个有特点的功能:
成员 | 类型 | 说明 |
---|---|---|
Clear | 方法 | 从Stack中移除所有对象 |
Contains | 方法 | 确定某元素是否在Stack中 |
Push | 方法 | 将对象插入Stack的顶部入栈 |
Pop | 方法 | 移除并返回Stack顶部的对象 出栈 |
Peek | 方法 | 返回位于Stack顶部的对象,但不移除,注意出栈是移除的。它不移除仅仅返回。 |
Count | 属性 | 获取Stack中包含的元素 |
static void Main(string[] args)
{
Stack s = new Stack();
s.Push(1);
s.Push("想回家了!");
s.Push(1.23);
Console.WriteLine(s.Peek()); //输出1.23
int Count = s.Count; //差点犯了逻辑错误,在for里面如果是s.Count的话,很容易乱,因为出栈操作s.Count是在变动着的。
for (int i = 0; i < Count; i++)
{
Console.WriteLine(s.Pop()); //输出 1.23 想回家了 1
}
Console.WriteLine(s.Count); //输出0
Stack<int> sInt = new Stack<int>();
sInt.Push(1);
sInt.Push(2);
sInt.Push(3);
Console.WriteLine(sInt.Peek()); //输出3
int IntCount = sInt.Count; //差点犯了逻辑错误,在for里面如果是s.Count的话,很容易乱,因为出栈操作s.Count是在变动着的。
for (int i = 0; i < IntCount; i++)
{
Console.WriteLine(sInt.Pop()); //输出 3 2 1
}
Console.WriteLine(sInt.Count); //输出0
Console.ReadKey();
}
5、SortedList
与SortedList
SortedList类实现了IDictionary、ICollection以及IEnumerable接口。SortedList类与HashTable类似,也表示一个键/值对集合,可以通过键和索引对元素进行访问,但不同的是,也是该类的最大作用所在,就是支持基于键的排序。在SortedList中,键和值分别保存在一个数组中,当向Sorted添加一个元素时,SortedList类添加一个元素时,SortedList会首先对key进行排序,然后根据排序结果计算出要插入到集合中的位置索引,再分别将key和value插入到各自数组的指定索引位置。当使用foreach循环集合中的元素时,SortedList会将相同索引位置的key和value放进一个DictionaryEntry类型的对象,然后返回。
C#集合之SortedList
static void Main(string[] args)
{
SortedList SL = new SortedList();
SL.Add("txt","txt"); //Add的时候会自动排序
SL.Add("jpg","jpg");
SL.Add("png","png");
foreach (DictionaryEntry de in SL) //返回的是DictionaryEntry对象
{
Console.Write(de.Key + ":" + de.Value + " "); //输出 jpg:jpg png:png txt:txt //注意这个顺序啊,添加的时候就自动排序了
}
Console.WriteLine();
SortedList<int,string> SLString = new SortedList<int,string>();
SLString.Add(3, "333");
SLString.Add(2, "222");
SLString.Add(1, "111");
foreach (KeyValuePair<int,string> des in SLString) //返回的是KeyValuePair,在学习的时候尽量少用var,起码要知道返回的是什么
{
Console.Write(des.Key + ":" + des.Value + " ");
}
Console.ReadKey();
}
6、BitArray
BitArray类实现了一个位结构,它是一个二进制位(0和1)的集合。BitArray的值表示true或false。true表示位打开,false表示位关闭。BitArray实现了ICollection和IEnumerable接口。
BitArray的一些特性如下:
1、BitArray集合不支持动态调整,因此没有Add和Remove方法。
2、若需要调整集合的大小,可通过设置属性Length的值来实现。
3、集合中的索引从0开始。
4、使用BitArray(int length)构造函数初始化BitArray集合后,其值均为false。
5、BitArray集合之间支持按位“或”、“异或”、“与运算”,参与这三类运算的BitArray集合长度必须相等。否则会抛出异常。
成员 | 说明 |
---|---|
Count | 获取 BitArray 中包含的元素数。 |
IsReadOnly | 获取一个值,该值指示 BitArray 是否为只读。 |
IsSynchronized | 获取一个值,该值指示是否同步对 BitArray 的访问(线程安全)。 |
Item | 获取或设置 BitArray 中特定位置的位的值。 |
Length | 获取或设置 BitArray 中元素的数目。 |
SyncRoot | 获取可用于同步 BitArray 访问的对象。 |
方法 | 说明 |
And | 对当前 BitArray 中的元素和指定的 BitArray 中的相应元素执行按位 AND 运算。 |
Clone | 创建 BitArray 的浅表副本。 |
CopyTo | 从目标数组的指定索引处开始将整个 BitArray 复制到兼容的一维 Array。 |
Get | 获取 BitArray 中特定位置处的位的值。 |
GetEnumerator | 返回循环访问 BitArray 的枚举数。 |
Not | 反转当前 BitArray 中的所有位值,以便将设置为 true 的元素更改为 false;将设置为 false 的元素更改为 true。 |
Or | 对当前 BitArray 中的元素和指定的 BitArray 中的相应元素执行按位“或”运算。 |
Set | 将 BitArray 中特定位置处的位设置为指定值。 |
SetAll | 将 BitArray 中的所有位设置为指定值。 |
Xor | 对当前 BitArray 中的元素和指定的 BitArray 中的相应元素执行按位“异或”运算。 |
static void Main(string[] args)
{
BitArray BA = new BitArray(3);
BA[0] = true;
BA[1] = false;
BA[2] = true;
BitArray BB = new BitArray(3);
BA[0] = true;
BA[1] = false;
BA[2] = true;
BitArray BOr = BA.Or(BB); //与运算,返回一个新的BitArray
foreach (var b in BOr)
{
Console.Write(b + "-"); //True-False-True
}
Console.ReadKey();
}
7、Dictionary 字典
方法 | 说明 |
---|---|
Add | 将指定的键和值添加到字典中 |
Clear | 从 Dictionary 中移除所有的键和值。 |
ContainsKey | 确定 Dictionary 是否包含指定的键。 |
ContainsValue | 确定 Dictionary 是否包含特定值。 |
Equals(Object) | 确定指定的 Object 是否等于当前的 Object。 (继承自 Object。) |
Finalize | 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。 (继承自 Object。) |
GetEnumerator | 返回循环访问 Dictionary 的枚举器。 |
GetHashCode | 用作特定类型的哈希函数。 (继承自 Object。) |
GetObjectData | 实现 System.Runtime.Serialization.ISerializable 接口,并返回序列化 Dictionary 实例所需的数据。 |
GetType | 获取当前实例的 Type。 (继承自 Object。) |
MemberwiseClone | 创建当前 Object 的浅表副本。 (继承自 Object。) |
OnDeserialization | 实现 System.Runtime.Serialization.ISerializable 接口,并在完成反序列化之后引发反序列化事件。 |
Remove | 从 Dictionary 中移除所指定的键的值。 |
ToString | 返回表示当前对象的字符串。 (继承自 Object。) |
TryGetValue | 获取与指定的键相关联的值。 |
属性 | |
Comparer | 获取用于确定字典中的键是否相等的 IEqualityComparer 。 |
Count | 获取包含在 Dictionary 中的键/值对的数目。 |
Item | 获取或设置与指定的键相关联的值。 |
Keys | 获取包含 Dictionary 中的键的集合。 |
Values | 获取包含 Dictionary 中的值的集合。 |
//定义
Dictionary<string, string> openWith = new Dictionary<string, string>();
//添加元素
openWith.Add("txt", "notepad.exe");
openWith.Add("bmp", "paint.exe");
openWith.Add("dib", "paint.exe");
openWith.Add("rtf", "wordpad.exe");
//取值
Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
//更改值
openWith["rtf"] = "winword.exe";
Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
//遍历key
foreach (string key in openWith.Keys)
{
Console.WriteLine("Key = {0}", key);
}
//遍历value
foreach (string value in openWith.Values)
{
Console.WriteLine("value = {0}", value);
}
//遍历value, Second Method
Dictionary<string, string>.ValueCollection valueColl = openWith.Values;
foreach (string s in valueColl)
{
Console.WriteLine("Second Method, Value = {0}", s);
}
//遍历字典
foreach (KeyValuePair<string, string> kvp in openWith)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
//添加存在的元素
try
{
openWith.Add("txt", "winword.exe");
}
catch (ArgumentException)
{
Console.WriteLine("An element with Key = \"txt\" already exists.");
}
//删除元素
openWith.Remove("doc");
if (!openWith.ContainsKey("doc"))
{
Console.WriteLine("Key \"doc\" is not found.");
}
//判断键存在
if (openWith.ContainsKey("bmp")) // True
{
Console.WriteLine("An element with Key = \"bmp\" exists.");
}
//参数为其它类型
Dictionary<int, string[]> OtherType = new Dictionary<int, string[]>();
OtherType.Add(1, "1,11,111".Split(','));
OtherType.Add(2, "2,22,222".Split(','));
Console.WriteLine(OtherType[1][2]);
//参数为自定义类型
//首先定义类
class DouCube
{
public int Code { get { return _Code; } set { _Code = value; } } private int _Code;
public string Page { get { return _Page; } set { _Page = value; } } private string _Page;
}
//声明并添加元素
Dictionary<int, DouCube> MyType = new Dictionary<int, DouCube>();
for (int i = 1; i <= 9; i++)
{
DouCube element = new DouCube();
element.Code = i * 100;
element.Page = "http://www.doucube.com/" + i.ToString() + ".html";
MyType.Add(i, element);
}
//遍历元素
foreach (KeyValuePair<int, DouCube> kvp in MyType)
{
Console.WriteLine("Index {0} Code:{1} Page:{2}", kvp.Key, kvp.Value.Code, kvp.Value.Page);
}