在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
先来了解下集合的基本信息 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 中。 属性 Count 获取 ICollection 中包含的元素数。 原来Count的源头在这里。 4、ICollection<T> 方法 说明 Count 获取 ICollection<(Of <(T>)>) 中包含的元素数。 属性 Add 将某项添加到 ICollection<(Of <(T>)>) 中。 这个ICollect<T>,才开始有点集合的影子了,可以Add、Clear了,怪不得它作为泛型集合接口的基类。 5、IList IList继承了ICollection和IEnumerable 方法 说明 Add 将某项添加到 IList 中。 属性 Count 获取 ICollection 中包含的元素数。 (继承自 ICollection。) 可以看到,在不断的继承过程中,这些接口不断地添加自己的东西,越继承越多,越继承越多。 6、IList<T> IList<T>继承了ICollection<T>,IEnumerable<T>,IEnumerable 方法 说明 Add 将某项添加到 ICollection<(Of <(T>)>) 中。 (继承自 ICollection<(Of <(T>)>)。) 属性 Count 获取 ICollection<(Of <(T>)>) 中包含的元素数。 (继承自 ICollection<(Of <(T>)>)。) 同样,在不断的继承中,增加了新的东西,功能也越来越强大,支持索引获取和设置就是IList<T>这个源头的。一直弄不明白,NHibernate为什么会选择这个接口来返回数据,其实这个接口的东西够用了。 7、IDictionary<TKey,TValue>接口 IDictionary<TKey,TValue>是最底层出现的键/值对集合了,相当于值集合中的ICollection<T> 方法 说明 Add 已重载。 属性 Count 获取 ICollection<(Of <(T>)>) 中包含的元素数。 (继承自 ICollection<(Of <(T>)>)。) 该接口提供的功能和ICollection<T>差不多,其实就是键/值对的开宗立派者。 8、IDictionary 方法 说明 Add 在 IDictionary 对象中添加一个带有所提供的键和值的元素。 属性 Count 获取 ICollection 中包含的元素数。 (继承自 ICollection。) 9、ISet<T> ISet<T>同样是继承自ICollection<T>,IEnumerable<T>,IEnumerable 方法 说明 Add(T) 将某项添加到 ICollection<T> 中。 (继承自 ICollection<T>。) 记住这些接口之间的关系,其实是非常重要的,方法和属性记不全也无所谓,但是需要记住各自提供的功能,以及继承关系。 先说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具体提供的功能 属性 说明 Capacity 获取或设置 ArrayList 可包含的元素数。 方法 Adapter 为特定的 IList 创建 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差不多,只不过存储的是键值对而已。只写个基本短小的示例。 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<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的作用。 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<int> qInt = new Queue<int>(); 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<T> 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<T> SortedList类实现了IDictionary、ICollection以及IEnumerable接口。SortedList类与HashTable类似,也表示一个键/值对集合,可以通过键和索引对元素进行访问,但不同的是,也是该类的最大作用所在,就是支持基于键的排序。在SortedList中,键和值分别保存在一个数组中,当向Sorted添加一个元素时,SortedList类添加一个元素时,SortedList会首先对key进行排序,然后根据排序结果计算出要插入到集合中的位置索引,再分别将key和value插入到各自数组的指定索引位置。当使用foreach循环集合中的元素时,SortedList会将相同索引位置的key和value放进一个DictionaryEntry类型的对象,然后返回。 看了下MSDN,功能还是差不多,而且不难看明白,实在没力气一个一个写DEMO了。 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集合长度必须相等。否则会抛出异常。 抱着MSDN来学习下: 属性 说明 Count 获取 BitArray 中包含的元素数。 方法 说明 And 对当前 BitArray 中的元素和指定的 BitArray 中的相应元素执行按位 AND 运算。 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(); } 各种集合的选用,可查看这篇文章:http://www.cnblogs.com/kissdodog/p/5419986.html |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论