C#中的ArrayList集合详解与深度探讨

来源:互联网 发布:linux如何查看raid 编辑:程序博客网 时间:2024/05/14 17:55

在C#中使用数组有其存在的两个无法避免的弊端:

1,数组储存的对象的数据类型必须一致,int数组只能储存int类型的数据,string数组只能储存string类型的数据,char数组只能储存char类型的数据...。

2,数组都是固定大小的,在声明数组的时候数组的大小就已经确定且不能改变。

以上两种弊端就决定了在实际应用中的局限性,而因为存在这样的弊端,通过数组不能解决的问题我们就可以通过集合来解决,因为集合没有这两个方面的弊端。


我们可以使用ArrayList集合来解决数组不能解决的储存数据类型限制和数组大小不能改变的问题。如:如果我们要储存不同数据类型的数据,且数据根据需要添加,而数据多少在声明的时候无法确定。


案例1)我们需要储存以下数据:

"姓名"、"1234"、"男"、"3.14"、"500m"

以上数据显然不能用数组进行储存和运算,因为都是不同类型,这里场景我们就可以使用ArrayList集合进行储存。代码如下:

ArrayList list1=new ArrayList();

list1.Add("姓名");

list1.Add(1234);

list1.Add('男');

list1.Add(3.14);

list1.Add(500m);

通过以上代码我们就可以将这五种类型的数据添加进ArrayList集合对象list1中。也可以将其输出出来:

for(int i=0;i<list1.Count;i++) //此处的循环条件应该是Count而绝非Length,在集合类型的长度用Count,数组用Length

{

Console.WriteLine("list1集合中的第{0}个元素是{1}",i+1,list1[i]);

}

输出结果如下:




虽然能够存储,也能够输出,但由于笔者也是初学者,疑问比较多,喜欢追根究底。当时笔者在学习ArrayList集合的时候有一个疑问,因为根据我们学习C#基础知识所学习的内容这显然不正常。一种什么数据类型能够储存各种数据类型的数据呢,这种储存的实质到底是什么?


后面笔者学到了面向对象,便开始从面向对象的角度去分析这个问题:

在面向对象的思想中所有类型都有一个共同的基类(父类)就是object型,而根据里氏转换的原则,所有子类都可以赋值给其父类储存。那么,这里的ArrayList集合对象list1的储存各种数据类型数据的实质是不是就是应用了这种转换,在把各种数据类型添加到list1对象的时候是不是就是将其转换成了object类型呢。

对于这点疑问我们就先看ArrayList类型对象的Add方法:


果然,通过ArrayList类型的方法参数我们可以看出,其实所谓的储存,只是将各种数据类型数据都转换成了object类型进行储存。这只是初步验证。下面我们进行进一步的验证:


根据里氏转换的原则,子类赋值(转换成)父类后,子类对象再也不具备子类的方法和属性,只具备父类的方法和属性。也就是说,如果ArrayList对象的Add方法的实质是将添加进ArrayList对象的数据转换成了object类型的话,此时的数据是不能够像被添加前一样进行加减乘除运算的(整型),因为此时添加进的数据已经不具备了其赋值之前的类型特征,而只拥有父类的特征。那么这就需要我们进行验证了。


我们将添加进list1对象的第二个数据“1234”让它加上任何一个整型,看是否会报错:

我们在以上代码中添加一行代码:

int result=list1[1]+6;

下面是执行结果:


很显然,报错了,报错文字解释了问题所在“运算符+无法应用于object和int类型的操作数”,也就是说,系统此时已经把list1[1]认定成了object类型,所以不能进行加法运算了。


测试到这里,当时笔者还有一个疑问,就是既然添加进ArrayList对象的数据不具备了原来的数据类型特征,那么为什么还能使用Console.WriteLine()进行输出呢。这就引发了我们对Console.WriteLine()方法的运行原理进行思考:


学习C#的朋友都知道,Console.WriteLine()方法的参数可以是任何类型,并且无论参数传入的是什么类型的对象,输出出来的永远都是string类型。那么是不是Console.WriteLine()方法的输出,都是调用了传入参数的ToString()方法呢。下面我们还是拿前面的循环输出list1对象里面的元素的例子进行验证。

我们将以下代码进行修改:

for(int i=0;i<list1.Count;i++) 

{

Console.WriteLine("list1集合中的第{0}个元素是{1}",i+1,list1[i]);

}

修改成:

for(int i=0;i<list1.Count;i++) 

{

Console.WriteLine("list1集合中的第{0}个元素是{1}",(i+1).ToString(),list1[i].ToString());

}

执行结果如下:


执行结果和修改前的一样,那么我们有必要这么思考,所谓的Console.WriteLine()方法的实质实际上就是将传入的参数都使用了ToString()方法进行输出。


好了,前面的都思考得差不多了,下面笔者记录一下ArrayList对象的常用方法和属性:

(1)属性:Count属性,返回ArrayList对象的元素的数目。

(2)方法:

1)Add()方法:添加对象到集合中。

2)Insert()方法:插入对象到集合中。

3)InsertRange()方法:插入集合对象到集合中。

4)Remove()方法:移除集合中的某个对象。

5)RemoveAt()方法:根据索引移除集合中的某个对象。

6)Clear()方法:清空集合中的所有对象。

7)Sort()方法:对集合中的所有对象进行排序。

9)Contains()方法:检查集合中是否存在某对象。

10)Reserve()方法:将集合中元素的顺序反转。

原创粉丝点击