C#: 集合

摘自http://www.cnblogs.com/kissdodog/archive/2013/01/29/2882195.html

先来了解下集合的基本信息

1、BCL中集合类型分为泛型集合与非泛型集合。

2、非泛型集合的类和接口位于System.Collections命名空间。

3、泛型集合的类和接口位于System.Collections.Generic命名空间。

  ICollection接口是System.Collections命名空间中非泛型集合类的基接口,它继承自IEnumerable接口,从IEnumerable接口继承意味着实现该接口的实现类需要实现一个枚举器方法:GetEnumerator,该方法返回IEnumerator类型的数据。IDictionary和IList接口继承自ICollection作为更为专用的接口,其中IDictionary接口是键/值对接口,它的实现如HashTable类;而IList是值的集合,其成员可通过索引访问,如ArrayList类,次类集合与数组相比,可以认为是可变的集合,优点有,长度自动增长等。IEnumerable<T>和IEnumerable是所有集合或集合接口的基接口,所有集合接口或集合都继承、实现了它。其中IEnumerable是最底层的接口。在非泛型集合里存放的都是System.Object类型。

一、下面列出非泛型和泛型集合的接口

非泛型集合接口          泛型集合接口              说明

ICollection            ICollection<T>             定义所有集合的大小(Count),枚举器(foreach)和同步(copyto)方法,继承自IEnumerable

IList               IList<T>                表示可按照索引单独访问的一组对象(像数组一样)

IDictionary             IDictionary<T>             表示键/值对的集合

IComparer              IComparer<T>               定义类型为比较两个对象而实现的方法

IEqualityComparer         IEqualityComparer<T>          定义方法以支持对象的相等比较

IEnumerable            IEnumerable<T>             公开枚举器。实现了该接口意味着允许foreach语句循环访问集合中的元素

IEnumerator            IEnumerator<T>             支持在泛型集合上进行简单迭代

下面来详细介绍各种集合接口和集合。个人认为应该从根底说起。

先抱着MSDN来说IEnumerable,扩展方法就不说了,扩展方法跳过,留到学Linq的时候再说。

1、IEnumerable接口就一个方法,没有属性。

  方法            说明

GetEnumerator         返回一个循环访问集合的枚举数。 实现或继承了该接口,就是为了这个方法,可以foreach遍历。



2、IEnumerable<T>接口也一样,也是就一个方法,没有属性。

  方法             说明

GetEnumerator         返回一个循环访问集合的枚举数。



3、ICollection接口

  方法             说明

  CopyTo           从特定的 Array 索引处开始,将 ICollection 的元素复制到一个 Array 中。 
  GetEnumerator       返回一个循环访问集合的枚举数。 (继承自 IEnumerable。)

  属性

  Count              获取 ICollection 中包含的元素数。 原来Count的源头在这里。
  IsSynchronized        获取一个值,该值指示是否同步对 ICollection 的访问(线程安全)。 
  SyncRoot           获取可用于同步 ICollection 访问的对象。



4、ICollection<T>

  方法               说明

  Count                获取 ICollection<(Of <(T>)>) 中包含的元素数。 
  IsReadOnly            获取一个值,该值指示 ICollection<(Of <(T>)>) 是否为只读。

  属性

  Add                 将某项添加到 ICollection<(Of <(T>)>) 中。 
  Clear                从 ICollection<(Of <(T>)>) 中移除所有项。 
  Contains              确定 ICollection<(Of <(T>)>) 是否包含特定值。 
  CopyTo              从特定的 Array 索引开始,将 ICollection<(Of <(T>)>) 的元素复制到一个 Array 中。 
  GetEnumerator          已重载。 
  Remove               从 ICollection<(Of <(T>)>) 中移除特定对象的第一个匹配项。

这个ICollect<T>,才开始有点集合的影子了,可以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<T>

  IList<T>继承了ICollection<T>,IEnumerable<T>,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<T>这个源头的。一直弄不明白,NHibernate为什么会选择这个接口来返回数据,其实这个接口的东西够用了。



7、IDictionary<TKey,TValue>接口

  IDictionary<TKey,TValue>是最底层出现的键/值对集合了,相当于值集合中的ICollection<T>

  方法            说明

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<T>差不多,其实就是键/值对的开宗立派者。



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<T>

  ISet<T>同样是继承自ICollection<T>,IEnumerable<T>,IEnumerable

方法            说明

Add(T)           将某项添加到 ICollection<T> 中。 (继承自 ICollection<T>。)
Add(T)           向当前集内添加元素,并返回一个指示是否已成功添加元素的值。
Clear            从 ICollection<T> 中移除所有项。 (继承自 ICollection<T>。)
Contains          确定 ICollection<T> 是否包含特定值。 (继承自 ICollection<T>。)
CopyTo            从特定的 Array 索引开始,将 ICollection<T> 的元素复制到一个 Array 中。 (继承自 ICollection<T>。)
ExceptWith         从当前集内移除指定集合中的所有元素。
GetEnumerator()       返回一个循环访问集合的枚举数。 (继承自 IEnumerable。)
GetEnumerator()       返回一个循环访问集合的枚举器。 (继承自 IEnumerable<T>。)
IntersectWith        修改当前集,使该集仅包含指定集合中也存在的元素。
IsProperSubsetOf      确定当前的设置是否正确 (严格) 指定集合的子集。
IsProperSupersetOf     确定当前的设置是否正确 (严格) 指定集合中的超集。
IsSubsetOf          确定一个集是否为指定集合的子集。
IsSupersetOf         确定当前集是否为指定集合的超集。
Overlaps            确定当前集是否与指定的集合重叠。
Remove             从 ICollection<T> 中移除特定对象的第一个匹配项。 (继承自 ICollection<T>。)
SetEquals           确定当前集与指定的集合中是否包含相同的元素。
SymmetricExceptWith    修改当前集,使该集仅包含当前集或指定集合中存在的元素(但不可包含两者共有的元素)。
UnionWith          修改当前设置,以使其包含当前集或指定的集合中的所有元素。

记住这些接口之间的关系,其实是非常重要的,方法和属性记不全也无所谓,但是需要记住各自提供的功能,以及继承关系。

先说IComparer接口,这个接口就一个方法,用于如何比较两个对象

 1 public class StringLengthComparer : IComparer<string>
 2     {
 3         public int Compare(string s1, string s2)
 4         {
 5             if (s1.Length > s2.Length)
 6             {
 7                 return (1);
 8             }
 9             else if (s1.Length < s2.Length)
10             {
11                 return (2);
12             }
13             else
14             {
15                 return (0);
16             }
17         }
18     }

说完了集合接口,现在开始说集合。

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具体提供的功能

属性              说明

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 中元素的实际数目。

  1 static void Main(string[] args)
  2         {
  3
  4             ArrayList arrayList = new ArrayList();
  5             arrayList.Add(1);                       //Add方法,将一个元素添加到ArrayList中
  6             arrayList.Add("你好");
  7             arrayList.Add(3.265);
  8             IList iList = arrayList;
  9             ICollection iCollection = iList;
 10             IEnumerable iEnumerable = iCollection;  //体现了ArrayList的继承关系
 11             foreach (object obj in iEnumerable)
 12             {
 13                 Console.WriteLine(obj.ToString());
 14             }
 15
 16             bool b = arrayList.Contains("你好");  //确定ArrayList中是否包含某元素
 17             Console.WriteLine(b);                 //输出 True
 18
 19             object[] objArr = new object[arrayList.Count + 1];
 20             objArr[0] = "我是用来占位的";
 21             arrayList.CopyTo(objArr, 1); //便宜一位,也就是接受数组从1开始,默认是0
 22             foreach (object obj in objArr)
 23             {
 24                 Console.Write(obj.ToString() + "-");    //输出 我是用来占位的-1-你好-3.265-
 25             }
 26             Console.WriteLine();
 27
 28             ArrayList AL = ArrayList.FixedSize(arrayList);  //静态方法 返回一个固定大小的ArrayList对象,数量不许改变。也就是说不能添加和删除。
 29             Console.WriteLine(AL.IsFixedSize);  //输出True
 30             //AL.Add(111); 此处报异常,"集合的大小是固定的"
 31             ArrayList ALReadOnly = ArrayList.ReadOnly(arrayList);
 32             Console.WriteLine(ALReadOnly.IsReadOnly);   //输出True
 33
 34
 35             ArrayList AL1 = arrayList.GetRange(1, 2);   //按照索引顺序截取出子集
 36             foreach (object obj in AL1)
 37             {
 38                 Console.Write(obj.ToString());  //输出 你好3.265    可以截取出的新ArrayList只包含1,2位
 39             }
 40             Console.WriteLine();
 41
 42             int indexLocation = arrayList.IndexOf(1);   //从左边开始检索,返回第一个匹配到的元素的顺序
 43             Console.WriteLine(indexLocation);   //输出  0
 44
 45             arrayList.Add(1);       //为了体现LastIndexOf的不同,先添加一个1
 46             int lastLocation = arrayList.LastIndexOf(1);
 47             Console.WriteLine(lastLocation);    //返回3
 48
 49             arrayList.Insert(2, "Insert插入的元素");  //这个方法与Add的不同在于它可以在任意位置插入
 50             foreach (object obj in arrayList)
 51             {
 52                 Console.Write(obj.ToString() + " ");    //输出 1 你好 Insert插入的元素 3.265 1
 53             }
 54
 55             ArrayList arr = new ArrayList();
 56             arr.Add(1);
 57             arr.Add(2);
 58             arrayList.AddRange(arr);
 59             foreach (object obj in arrayList)
 60             {
 61                 Console.Write(obj.ToString() + "-");    //输出 1 你好 Insert插入的元素 3.265 1 1 2可以看到将一个新的集合追加到了最后
 62             }
 63
 64             arrayList.Remove(2);
 65             foreach (object obj in arrayList)
 66             {
 67                 Console.Write(obj.ToString() + "-");    //输出 1 你好 Insert插入的元素 3.265 1 1 可以看到2已经被移除了
 68             }
 69             Console.WriteLine();
 70
 71             arrayList.RemoveAt(0);
 72             foreach (object obj in arrayList)
 73             {
 74                 Console.Write(obj.ToString() + "-");    //输出 你好 Insert插入的元素 3.265 1 1 可以看到第0个元素"2"已经被移除了
 75             }
 76             Console.WriteLine();
 77
 78             //arrayList.Reverse();
 79             //foreach (object obj in arrayList)
 80             //{
 81             //    Console.Write(obj.ToString() + "-");        //输出顺序倒转的所有元素
 82             //}
 83
 84             ArrayList AL3 = new ArrayList();
 85             arrayList.SetRange(0,AL3);      //从第0位开始,将元素复制到AL3中
 86             foreach (object obj in AL3)
 87             {
 88                 Console.Write(obj.ToString() + "-");    //输出 你好 Insert插入的元素 3.265 1 1
 89             }
 90
 91             object[] objArrs = new object[arrayList.Count];
 92             objArrs = arrayList.ToArray();
 93             foreach (object obj in objArrs)
 94             {
 95                 Console.Write(obj.ToString() + "-");
 96             }
 97
 98             Console.WriteLine();
 99
100             arrayList.Capacity = 5;     //读取或设置可包含元素的数量,如果小于当前会报错。
101             Console.WriteLine(arrayList.Count);     //输出5
102             arrayList.TrimToSize();
103             Console.WriteLine(arrayList.Count);     //输出5
104
105             Console.ReadKey();
106         }

2、非泛型集合HashTable

  Hashtable实现了IDictionary、ICollection以及IEnumerable接口。注意Hashtable,t是小写的。由于是非泛型集合,因此存储进去的都是object类型,不管是键还是值。

  Hashtable的要点。

  (1)、Hashtable仅有非泛型版本。

  (2)、Hashtable类中的键不允许重复,但值可以。

  (3)、Hashtable类所存储的键值对中,值可以为null,但键不允许为null。

  (4)、Hashtable不允许排序操作。

  以下给出一个实例,Hashtable提供的功能是在于ArraryList差不多,只不过存储的是键值对而已。只写个基本短小的示例。

 1 static void Main(string[] args)
 2         {
 3             Hashtable ht = new Hashtable();
 4             ht.Add(1,1);
 5             ht.Add("我爱你","是吗?");
 6             Console.WriteLine(ht.Count);    //输出 2
 7             Console.WriteLine(ht["我爱你"]);   //输出 "是吗?"  用键 获取值
 8             Console.WriteLine(ht.Contains(1));  //输出True
 9
10             Console.ReadKey();
11         }

3、Queue和Queue<T>

  Queue成为队列,队列是这样一种数据结构,数据有列表的一端插入,并由列表的另一端移除。就像单行道,只能从一段进,从一端出。Queue类实现了ICollection和IEnumerable接口。

  Queue的一些重要特性。

  1、先进先出

  2、可以添加null值到集合中

  3、允许集合中的元素重复

  4、Queue容量会按需自动添加

  5、Queue的等比因子是当需要更大容量时当前容量要乘以的数字,默认是2.0。

  现在列出Queue一个特性的功能

成员       类型        说明

Clear       方法        从Queue中移除所有对象,清空队列。

Contains     方法        确定某元素是否在Queue中

Enqueue     方法        将对象添加到Queue的结尾处  入列

Dequeue     方法        移除并返回位于Queue开始处的对象  出列

Peek       方法        返回位于Queue开始出的对象,但不将其移除,与出列不同,出列是会移除的

  提供的功能都是差不多的,现在给出一个实例,主要显示Queue的作用。

 1 static void Main(string[] args)
 2         {
 3             Queue q = new Queue();
 4             q.Enqueue(1);
 5             q.Enqueue("想家了!");
 6             q.Enqueue(1.23);
 7             Console.WriteLine(q.Peek());    //输出1 获取值但不移除,与出列不同
 8             int Count = q.Count;            //出队的时候q.Count在变化,因此q.Count放在循环条件里是不妥的
 9             for (int i = 0; i < Count; i++)
10             {
11                 Console.WriteLine(q.Dequeue().ToString());  //注意 输出 1 想家了 1.23  都是从最先添加的先拿
12             }
13             Console.WriteLine(q.Count); //输出0 出列一次,就自动移除了。
14
15             Queue<int> qInt = new Queue<int>();
16             qInt.Enqueue(1);
17             qInt.Enqueue(2);
18             qInt.Enqueue(3);
19             Console.WriteLine(qInt.Peek());     //输出1
20             int IntCount = qInt.Count;
21             for (int i = 0; i < IntCount; i++)
22             {
23                 Console.WriteLine(qInt.Dequeue());  //注意 输出 123  都是从最先添加的先拿
24             }
25             Console.WriteLine(q.Count); //输出0 出列一次,就自动移除了。
26
27             Console.ReadKey();
28         }

4、Stack和Stack<T>

  Stack称为栈,栈和队列非常相似,只不过队列是先进先出,而栈中的数据添加和移除都在一端进行,遵守栈中的数据则后进先出。Stack类实现了ICollection和IEnumerable接口。

  Stack类的一些重要特性如下:

  1、后进先出。

  2、可以添加null值到集合中。

  3、允许集合中的元素重复。

  4、Stack的容量会按需自动增加。

列出几个有特点的功能。

成员      类型        说明

Clear      方法         从Stack中移除所有对象

Contains    方法         确定某元素是否在Stack中

Push      方法         将对象插入Stack的顶部  入栈

Pop      方法         移除并返回Stack顶部的对象  出栈

Peek       方法         返回位于Stack顶部的对象,但不移除,注意出栈是移除的。它不移除仅仅返回。

Count      属性         获取Stack中包含的元素

 1 static void Main(string[] args)
 2         {
 3             Stack s = new Stack();
 4             s.Push(1);
 5             s.Push("想回家了!");
 6             s.Push(1.23);
 7             Console.WriteLine(s.Peek());    //输出1.23
 8
 9             int Count = s.Count;    //差点犯了逻辑错误,在for里面如果是s.Count的话,很容易乱,因为出栈操作s.Count是在变动着的。
10             for (int i = 0; i < Count; i++)
11             {
12                 Console.WriteLine(s.Pop());     //输出 1.23 想回家了 1
13             }
14             Console.WriteLine(s.Count);     //输出0
15
16
17             Stack<int> sInt = new Stack<int>();
18             sInt.Push(1);
19             sInt.Push(2);
20             sInt.Push(3);
21             Console.WriteLine(sInt.Peek());    //输出3
22
23             int IntCount = sInt.Count;    //差点犯了逻辑错误,在for里面如果是s.Count的话,很容易乱,因为出栈操作s.Count是在变动着的。
24             for (int i = 0; i < IntCount; i++)
25             {
26                 Console.WriteLine(sInt.Pop());     //输出 3 2 1
27             }
28             Console.WriteLine(sInt.Count);     //输出0
29
30
31             Console.ReadKey();
32         }

5、SortedList与SortedList<T>

  SortedList类实现了IDictionary、ICollection以及IEnumerable接口。SortedList类与HashTable类似,也表示一个键/值对集合,可以通过键和索引对元素进行访问,但不同的是,也是该类的最大作用所在,就是支持基于键的排序。在SortedList中,键和值分别保存在一个数组中,当向Sorted添加一个元素时,SortedList类添加一个元素时,SortedList会首先对key进行排序,然后根据排序结果计算出要插入到集合中的位置索引,再分别将key和value插入到各自数组的指定索引位置。当使用foreach循环集合中的元素时,SortedList会将相同索引位置的key和value放进一个DictionaryEntry类型的对象,然后返回。

  看了下MSDN,功能还是差不多,而且不难看明白,实在没力气一个一个写DEMO了。

 1 static void Main(string[] args)
 2         {
 3             SortedList SL = new SortedList();
 4             SL.Add("txt","txt");                    //Add的时候会自动排序
 5             SL.Add("jpg","jpg");
 6             SL.Add("png","png");
 7             foreach (DictionaryEntry de in SL)      //返回的是DictionaryEntry对象
 8             {
 9                 Console.Write(de.Key + ":" + de.Value + "  ");  //输出 jpg:jpg png:png txt:txt    //注意这个顺序啊,添加的时候就自动排序了
10             }
11
12             Console.WriteLine();
13             SortedList<int,string> SLString = new SortedList<int,string>();
14             SLString.Add(3, "333");
15             SLString.Add(2, "222");
16             SLString.Add(1, "111");
17             foreach (KeyValuePair<int,string> des in SLString)  //返回的是KeyValuePair,在学习的时候尽量少用var,起码要知道返回的是什么
18             {
19                 Console.Write(des.Key + ":" + des.Value + " ");
20             }
21
22             Console.ReadKey();
23         }

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集合长度必须相等。否则会抛出异常。

抱着MSDN来学习下:

属性          说明

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 中的相应元素执行按位“异或”运算。

 1 static void Main(string[] args)
 2         {
 3             BitArray BA = new BitArray(3);
 4             BA[0] = true;
 5             BA[1] = false;
 6             BA[2] = true;
 7
 8             BitArray BB = new BitArray(3);
 9             BA[0] = true;
10             BA[1] = false;
11             BA[2] = true;
12
13             BitArray BOr = BA.Or(BB); //与运算,返回一个新的BitArray
14             foreach (var b in BOr)
15             {
16                 Console.Write(b + "-");     //True-False-True
17             }
18
19             Console.ReadKey();
20         }

时间: 2024-10-07 05:28:52

C#: 集合的相关文章

数组、字符串、集合

数组与集合的转换.数组与字符串的转换 ========数组变集合 String[] arr = {"abc","cc","kkkk"}; //把数组变成list集合有什么好处? /* 可以使用集合的思想和方法来操作数组中的元素. 注意:将数组变成集合,不可以使用集合的增删方法. 因为数组的长度是固定. contains. get indexOf() subList(); 如果你增删.那么会产生UnsupportedOperationExcepti

C#语言中数组和集合

数组.集合→用于储存多个同类型的数据数组 定长→用于保存固定数量的数据 在功能上,数组能实现的所有功能,集合都能实现:反之,集合能实现的某些功能,数组难以实现 占用内存少 便利速度快集合 不定长→保存的数据数量,可以在程序的执行过程中,发生变化 占用内存多 便利速度慢课时六:数组和集合 数组.集合→用于储存多个同类型的数据 数组 定长→用于保存固定数量的数据 在功能上,数组能实现的所有功能,集合都能实现:反之,集合能实现的某些功能,数组难以实现 占用内存少 便利速度快 集合 不定长→保存的数据数

通过反射了解集合泛型的本质

通过反射了解集合泛型的本质 import java.lang.reflect.Method; import java.util.ArrayList; /** * 通过反射了解集合泛型的本质 * @author shm * */ public class MethodDemo02 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add(

Java 之集合

collection(单列集合) List(有序,可重复) ArrayList     底层数据结构是数组,查询快,增删慢,线程不安全,效率高 Vector     底层数据结构是数组,查询快,增删慢,线程安全,效率低 LinkedList  底层数据结构是链表,查询慢,增删快,线程不安全,效率高 Set(无序,唯一) HashSet   底层数据结构是哈希表,依赖hashCode()和equals() 执行顺序:判断hashCode()是否相同,相同继续执行equals(),返回true不添加

集合和三元运算符

一.三元运算符 如下判断可以使用三元运算更方便的实现: a = 1b = 2 if a > 1: c = aelse: c = b 和下面是一样的: a = 1b = 2#下面这个c = a if a>1 else b 如下两种方法也是一样的:方式一: s=[]nums = list(range(1,11))for i in nums: if i%2==0: s.append(i)print(s)方式二:ss = [i for i in nums if i%2==0]print(ss)#这两种

集合函数 day4

1.集合 通过set强制转换,或者直接定义 1 nums = [0, 2, 4, 6, 8]#两种格式,带大括号与带中括号的 2 print(type(nums)) 3 aa = {0, 8, 2, 4, 6}#需要注意与字典的区别,字典是有分号的 2.交集

js算法集合(一) 水仙花数 及拓展(自幂数的判断)

js算法集合(一) ★ 最近有些朋友跟我说对js中的一些算法感到很迷惑,知道这个算法到底是怎么回事,但是就是不会用代码把它写出来,这里我跟大家分享一下做水仙花数的算法的思路,并对其扩展到自幂数的算法,希望能对大家有所帮助. 1.验证一个数是否为水仙花数 ①要写水仙花数的算法,我们首先来了解一下什么是水仙花数,水仙花数是指一个 3位正整数 ,它的每个位上的数字的 3次幂之和等于它本身.(例如:1^3 + 5^3+ 3^3 = 153): ②了解了什么是水仙花数我们就开始分析该怎么下手.通过定义来看

笔记:多线程-集合

阻塞队列(BlockingQueue) 当试图向队列添加元素而队列已满,或是想从队列移除元素而队列为空的时候,阻塞队列导致线程阻塞,阻塞队列接口定义如下,他继承Queue<E>接口: public interface BlockingQueue<E> extends Queue<E> { ????/** ???? * 添加一个元素,如果队列满,则抛出 IllegalStateException异常 ???? */ ????????boolean add(E e); ??

SQL入门之集合操作

尽管可以在与数据库交互时一次只处理一行数据,但实际上关系数据库通常处理的都是数据的集合.在数学上常用的集合操作为:并(union),交(intersect),差(except).对于集合运算必须满足下面两个要求: 两个数据集合必须具有同样数目的列 连个数据集中对应列的数据类型必须是一样的(或者服务器能够将其中一种类型转换为另一种类型) SQL语言中每个集合操作符包含两种修饰:一个包含重复项,另一个去除了重复项(但不一定去除了所有重复项). 0.union操作符 union和union all操作

Java—集合框架List

集合的概念 现实生活中:很多的事物凑在一起 数学中的集合:具有共同属性的事物的总和 Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象 集合的作用 在类的内部,对数据进行组织(针对作用与意义一样的属性,将他们放到一个集合中) 简单而快速的搜索大数量的条目 有的集合接口,提供了一系列排列有序的元素,并且可以在序列中快速的插入或删除有关元素 有的集合接口,提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意类型 与数组相比 数组的长度