当前位置:文档之家› 第4章 数组和集合

第4章 数组和集合


3
4.1 集合


集合相当于容器,用于将一系列相似的项组合在 一起。 集合可分为泛型集合类和非泛型集合类。 多数集合类都派生自ICollection、IComparer、 IEnumerable、IList、IDictionary和 IDictionaryEnumerator接口以及它们的等效泛型 接口,可继承这些接口来创建新集合类。
7

选择集合类时,一般要考虑以下问题:




需要先进先出行为时,可考虑使用Queue类和Queue<T>泛型类。 需要后进先出行为时,可考虑使用Stack类和Stack<T>泛型类。 需要通过索引号访问元素时,可考虑使用ArrayList、StringCollection 以及List<T>泛型类。 需要通过键值访问元素时,可考虑使用Hashtable、SortedList、 ListDictionary、StringDictionary类以及Dictionary<TKey, TValue>和 SortedDictionary<TKey, TValue>泛型类。 需用与输入元素方式不同的方式对元素排序时,可考虑Hashtable是按 元素的哈希代码对元素排序,SortedList以及SortedDictionary根据 IComparer实现按键对元素排序。 需要只接受字符串的集合时,可考虑使用StringCollection和 StringDictionary等。
4


普通集合就是这个集合可以添加任何类型的数据。 取出时,数据是object类型,一般需要进行强制类 型转换,但有时因为不确定存进去的是哪种数据 类型,有可能出现异常。 泛型就是添加了一个类型参数,只能添加指定数 据类型的数据,取出数据时,不用进行类型转换。 泛型是C# 2.0中的新增元素(C++中称为模板),主 要用于解决一系列类似的问题。这种机制允许将 类名作为参数传递给泛型类型,并生成相应的对 象。
foreach (类型 变量名 in 数组或集合表达式) { //具体处理语句 }

foreach只是遍历了数组元素的只读复本,而for语句是可以 用来更改数组或集合内容的。
15

在如下情形下,却不得不使用for:

只遍历部分数组。 只知道元素索引但不知道元素的值或类型。 foreach只能顺序遍历,如果想反向遍历,只能用for。
5


将泛型(包括类、接口、方法、委托等)看作模板可 能更好理解,模板中的变体部分将被作为参数传 进来的类名称所代替,从而得到一个新的类型定 义。 泛型就是添加了一个类型参数,只能添加指定数 据类型的数据,取出数据时,不用进行类型转换。 比如,List<string>直接使用string对象作为List的 元素,而避免使用object对象带来的封箱、拆箱操 作,从而提高程序性能。泛型集合类一般位于 System.Collections.Generic命名空间。
20
数组序列常用属性和方法
4.3.1 创建ArrayList

利用ArrayList的构造函数来创建一个新的列表,常用的形式有 以下两种: (1)public ArrayList() (2)public ArrayList(int capacity) 参数capacity可以指定所创建列表的初始容量。如果不指定, 则初始容量为.NET的默认值16。下面的代码创建了两个列表 对象:
4.3.4 查找元素


在集合中对特定元素的查找也是常用的操作之一,ArrayList提供了二分查 找的方法BinarySearch,可以在复杂度O(logn)内完成查找, 如果使用制定的排序策略对集合中的元素进行排序之后,相应地,也可以 使用同样的排序策略,结合BinarySearch方法实现元素的查找。这时,形 式如下: public virtual int BinarySearch(object value,IComparer comparer); 此时,将使用指定的比较器在整个已排序的ArrayList中搜索元素,并返回 该元素从零开始的索引。参数value为待查找的元素,而Icomparer为指定 的比较策略。



(1)public void Remove(object obj):用于删除数组 中特定对象obj的第一个匹配项。参数obj为要从 ArrayList移除的Object; (2)public void RemoveAt(int index):用于移除 ArrayList的指定索引处的元素。参数index为要移除的元 素的从零开始的索引; (3)public void RemoveRange(int index,int count): 用于从ArrayList中移除一定范围的元素。参数index为要 移除元素的起始索引(从零开始计数),参数count为 要移除的元素数。
•习题1 定义一个学号数组和一个姓名数组,利用Sort根据关键字(学号)对 姓名进行排序。
17
数组应用的实例

本节实现一个完整的示例:我的书房之图书排序。其功能为按照一定的排 列顺序显示一系列图书信息,最终实现结果如图4-1所示。 1.Book类 2.BookList类 3.主函数 习题2 扩展该例程,实现以下功能: 添加一本新书到列表中 显示图书价格大于参数min的所有图书 根据书名、作者或者价格,查找某本图书
实例Clone
复制值类型数组和引用类型数组的元素
13
静态方法Sort 静态方法Reverse 静态方法IndexOf 静态方法LastIndexOf
对一维数组排序 将一维数组或其部分元素逆序 返回一个数值在一维数组内第一次出现的序号 返回一个数值在一维数组内最后一次出现的序号
静态方法Copy
将一个数组对象的一部分复制到另一个数组对象中,并根 据需要进行强制类型转换和装箱
10

以下代码列出了对一维数组定义和初始化的方法, 其结果是相同的:

方式1:int [] myarray = new int [3] {1,2,3}; 方式2:int [] myarray = new int [] {1,2,3}; 方式3:int [] myarray = {1,2,3};
19

ArrayList与Array的区别主要体现在:



Array的大小是固定的;ArrayList的大小可根据需要自 动扩充。 Array中一次只能获取或设置一个元素的值;在 ArrayList中允许添加、插入或移除某一范围的元素。 Array的下限可以自定义;ArrayList的下限始终为零。 Array可以具有多个维度;ArrayList只能是一维。 Array位于System命名空间;ArrayList位于 System.Collections命名空间。
8
4.2 数组Array




数组继承自System.Array公共基类,是包含相同数 据类型元素的集合。 数组元素没有名称,只能通过索引来访问,索引 从零开始,可通过其索引来访问数组元素。 数组元素可以是任何类型,而数组元素的个数称 为数组长度。 数组有矩形数组(retangular arrays,含一维和二 维)、交错(锯齿型)数组(jagger arrays)、嵌套数组 等。
4.3 数组序列ArrayList



如果在程序运行时无法事先得到数组长度,则使 用数组序列ArrayList来保存数据。 ArrayList初始化时不需要指定数组长度(但仍可以 通过其Count属性判断长度),该类既有数组的特 性又有集合的特点。 它既可以通过下标访问元素、对元素排序、搜索, 又可以像处理集合一样添加、插入及删除元素。


(1)public int Add(object value) (2)public void AddRange(ICollection c)

Add和AddRange方法只能将元素添加到列表的末尾,如果想 要在列表的任意位置添加元素,则需要使用Insert方法。
4.3.3 删除元素

ArrayList中支持删除元素的方法有3个,形式分别 如下:
11
表4.1 Array类的主要属性 属性名 IsReadOnly IsFixedSize Length 说明 显示一个值,用于表示数组是否为只读 状态 显示一个值,用于表示数组是否具有固 定大小 获取数组所有维度上元素的总数
Rank
获取数组的维数
12
表4.2 Array类的部分主要方法
方法名 Initialize SetValue 实例方法GetValue 实例方法GetLength 说明 初始化Array类数组对象中各元素 将当前Array类数组对象的指定元素设置为指定数值 获取当前Array类数组对象的元素数值 获取当前Array类数组对象中指定维度的元素个数
9


数组一般需实例化后使用。声明和初始化可以在 一条语句中完成。 数组的声明和创建语句如下:数组类型[] 数组名 = new 数组类型[数组长度],其中的数组长度省 略时,由编译器根据初始化表中的数据个数自动 计算数组大小。如语句:数组名 = new int [4];分 配给数组4个整数存储空间。


索引器是一种特殊的类成员,能够让对象以类似数组的方式来存取,通过 对象元素的下标,可以访问指定的对象。 泛型引入了类型参数的概念,使得类和方法将对类型的指定推迟到实例化 该类和方法时再进行,可提供更高的类型安全性。
2

本章重点内容


了解.NET中常见的集合类,掌握常用集合类的 创建和操作方法。 理解索引器的概念,掌握其使用方法。 了解泛型的相关概念,掌握泛型接口、泛型类、 泛型属性和泛型方法的使用。
相关主题