什么是集合?
一、对象组
数组是System.Array类的一个实例。
System.Array有两个优点:可以高效地访问给定下标的元素;这个类有自己的C#语法,使用它编程非常直观。从但是,数组有一个缺点,即在实例化时需要指定数组的大小。以后也不能添加、插入或删除元素。数组还必须有一个数字下标,这样才能访问期中的元素。
.NET中的数据结构:集合、数组列表、栈、队列、有序列表、字典(有时也称为映射)。
除了基类System.Array以外,其他的数据结构类都在System.Collections命名空间中。
一.1
集合:表示一组可以通过遍历每个元素来访问的一组对象,特别是可以使用foreach循环来访问它们。
1)、集合的概念
对象如果可以提供相关对象的引用,就是一个集合,也被称为枚举,它可以遍历集合中的数据项。集合必须实现接口System.Collections.IEnumerable.IEnumerable只定义了一个方法:
interface4 IEnumerable
{
IEnumerator GetEnumerator();
}
GetEnumerator()的目的是返回枚举对象。
ICollection集合接口派生于IEnumerable.
interface IEnumerator
{
object Current{get;}
bool MoveNext();
void Reset();
}
IEnumerator的工作方式:实现该接口的对象应与一个集合相关联,这个对象在第一次初始化时,还没有指向集合中的任何元素,必须调用MoveNext(),移动枚举,才能使它指向集合中的第一个元素。Current属性获取该元素,Current属性返回一个对象引用,必须把它的数据类型转换为要在集合中查找的对象类型。之后两次调用MoveNext()方法,移动到集合的下一个元素上。重复这个过程,直到集合中没有元素为止,当Current属性返回null时,就表示到达了集合的末尾。
如果要返回到集合的开头,可以随时调用Reset()方法。注意Reset()方法实际上返回到集合开头前面的位置,如果要调用这个方法,就需要接着调用MoveNext(),指向第一个元素。
数组也是集合,foreach命令可以用于数组。这种特殊情况,System.Array类提供的枚举可以按照从0开始的来遍历其中的元素。
C#中,foreach循环只是一种语法上的简写方式,它内部的完整形式为:
{
Ienumerator enumerator = MessageSet.GetEnumerator();
string nextMessage;
emumerator.MoveNext();
while((nextMessage = enumerator.Current) != null)
{
DoSometing(nextMessage);
enumerator.MoveNext();
}
}
集合的一个方面是枚举作为一个单独的对象返回。
2)、给Vector结构添加集合支持
迭代Vector中的元素:
foreach(double component in someVector)
Console.WriteLine("Component is " + component);
让Vector实现IEnumerable接口,修改Vector结构的声明:
struct Vector:IFormattable,IEnumerable
{
public double x,y,z;
}
实现IEnumerable接口
public IEnumerator GetEnumerator()
{
return new VectorEnumerator(this);
}
VectorEnumerator不是外部代码需要直接访问的类,它声明为Vector结构中的私有类:
private class VectorEnumerator : IEnumerator
{
Vector theVector; // Vector object that this enumerato refers to
int location; // which element of theVector the enumerator is currently referring to
public VectorEnumerator(Vector theVector)
{
this.theVector = theVector;
location = -1;
}
public bool MoveNext()
{
++location;
return (location > 2) ? false : true;
}
public object Current
{
get
{
if (location < 0 || location > 2)
throw new InvalidOperationException(
"The enumerator is either before the first element or " +
"after the last element of the Vector");
return theVector[(uint)location];
}
}
public void Reset()
{
location = -1;
}
}
.2数组列表
ArrayList类与StringBuilder类:StringBuilder类可以分配足够的存储单元来存储一定量的字符,允许在该空间中处理字符,ArrayList类也是这样。ArrayList类的容量会自动增大,新增的内存区域可以存储当前容量两倍的元素,并重新定位这些元素。
ArrayList的实例化的最简单形式如下 :ArrayList baseballTeams = new ArrayList();
ArrayList baseballTeams = new ArrayList(20);
如果要把指定范围内的项复制到新的ArrayList中,就可使用GetRange()。
GetRange()方法有一个参数,第一个参数是开始复制的索引位置,第二个参数是要复制的元素个数。
SetRange()和InsertRange()方法也可以在ArrayList中旋转元素。
StringBuilder类没有把数组列表转换为数组的方法。必须使用一个循环手工复制引用。注意:只能复制引用,不能复制对象,所以不会对性能产生大的影响:
string[] myStringArray = new string[baseballTeams.Count];
for(int i = 0;i < baseballTeams.Count;i ++)
{
myStringArray[i] = (string)baseballTeams[i];
}
.3 Stack类
栈:是另一种集合类型,适合于处理应用程序使用完后就删除的临时数据项。Stack类创建集合是以后进先出(LIFO)的结构。
Stack类中的方法:
Clear:删除集合中的所有项
Clone:创建集合的浅度拷贝
CopyTo:把集合复制到已有的一维数组中
GetEnumerator:给集合返回一个枚举
Peek:返回栈中最上面的元素,但不把它从集合中删除
Pop:返回栈中最上面的元素,之后把它从集合中删除
Push:在栈中放置元素
ToArray:把栈复制到一个新数组中
.4 Queue类
Queue类以先进先出(FIFO)的结构创建集合。
其中方法:
Clear:删除集合中的所有项
Clone:创建集合的浅度拷贝
Contains:确定某个元素是否在集合中
CopyTo:把集合复制到已有的一维数组中
Dequeue:返回队列中的第一个对象,之后把它从集合中删除
Enqueue:在队列中放置元素
GetEnumerator:给集合返回一个枚举
Peek:返回队列中最前面的元素,但不把它从集合中删除
ToArray:把队列复制到一个新数组中
.5 SortedList类
SortedList集合中每一项都会指定一个用于引用该项的标识键。
使用Add()方法在该集合中放置元素。
GetKeyList()和GetValueList()方法,可以迭代SortedList集合的值和键。
迭代footballTeams集合的值:
foreach(string item in footballTeams.GetValueList())
{
Console.WriteLine(item);
}
迭代SortedList集合中的键:
foreach(string item in footballTeams.GetKeyList())
{
Console.WriteLine(item);
}
其中方法:
Add:把元素放在集合中
Clear:删除集合中的所有元素
Clone:创建集合的浅度拷贝
ContainsKey:根据键值确定某个元素是否在集合中
ContainsValue:根据项的值确定某个元素是否在集合中
CopyTo:把集合复制到已有的一维数组中
GetByIndex:返回指定索引的元素值
GetEnumerator:为集合返回一个枚举
GetKey:返回指定键的元素值
GetKeyList:从SortedList中返回键的集合
GetValueList:从SortedList中返回值的集合
Remove:根据元素的键值返回集合中的一个元素
RemoveAt:根据元素的索引值返回集合中的一个元素
SetByIndex:替换集合中指定索引的值