集合和泛型3-----集合2 ArrayList类

10.2.2.2集合类

在命名空间System.Collections中提供的集合类主要有类ArrayList、类Stack、类Hashtable、类BitArray、类Queue、类SortedList。这些类中除BitArray外,有一个共同的特点,就是在这些类的定义中,项的类型都是Object类型,所以允许在这些集合中存储任何c#中合法的类型。这样实现的原因主要是为了让用户使用方便,因为Object是任何类型的基类。其他类型的对象在进入这些集合的时候不需要进行类型转换,因为c#能够进行子类到基类的自动转换。

l         ArrayList类其实就是一个数组,只不过这个数组能够按需要动态增加空间。在空间改变时,因为改变的时机不同,算法执行的复杂度可能也不相同。因为ArrayList类就是对数组的一个包装,所以除了具有数组的一般属性与方法外,还有一些自己独有的属性与方法。

10-3ArrayList类的属性

10-3

属性名

说明

Capacity

获取或设置 ArrayList 可包含的元素数

Count

获取ArrayList中实际包含的元素数

IsFixedSize

获取一个值,该值指示ArrayList是否具有固定大小

IsReadOnly

获取一个值,该值指示ArrayList是否为只读

Item

获取或设置指定索引处的元素

10-4ArrayList类特有的一些方法列表

10-4

方法名

功能说明

Add

将对象添加到ArrayList的结尾处

AddRange

将另一个集合的所有元素批量添加到ArrayList的末尾

Contains

确定某元素是否在ArrayList

FixedSize

返回固定大小的ArrayList,其中的元素允许修改,但不允许添加或移除

GetRange

从源ArrayList中取出其中的一个子集返回

Insert

将元素插入ArrayList的指定索引处

InsertRange

将一个集合整体批量地插入到ArrayList的指定索引处

ReadOnly

返回一个与原ArrayList相同的ArrayList,返回的ArrayList具有只读的性质

Remove

ArrayList中移除特定对象的第一个匹配项

RemoveAt

在指定索引处移除ArrayList的元素

RemoveRange

ArrayList中移除一定范围的元素

Repeat

返回一个ArrayList,它的元素是指定值的重复拷贝

SetRange

从指定位置用另一个集合批量覆盖原ArrayList的项的值

ToArray

ArrayList的元素复制到新数组中

TrimToSize

将容量设置为ArrayList中元素的实际数目

ArrayList类的对象生成的时候,系统在对象内部放置了一个内置的数组,并为该内置数组开辟了一个Capacity大小的空间,随着数据的存储,Count不断变化,当Count等于或者超过Capacity时,系统会给该对象重新开辟一个新的内置数组,并把旧的内置数组的内容赋值过去。算法的复杂度是O(Capacity)

ArrayList的对象中插入一个新项,如果插入的位置LocationCount,并且Count小于Capacity时,将新项直接插入ArrayList,如果插入的位置Location不是Count,而且Count+1小于Capacity,则将插入位置后的元素后移,然后插入新项,算法的复杂度是O(Count-Location),如果在第一个元素前插入一个新的元素,算法的复杂度将是O(Count)。总之,ArrayList的运行原理基本同数组的操作。

例子ArrayListSample中演示了ArrayList一些方法与属性的使用。为了显示方便,在该例中首先编写了两个静态的函数,分别用来打印ArrayList的属性与元素。代码如下:

using System;

using System.Collections;//注意这里的命名空间的名称

using System.Linq;

using System.Text;

namespace ArrayListSample

{

    class Program

    {

        static void Main(string[] args)

        {

            ArrayList al = new ArrayList();

            PrintProperty("al",al);

            //al中添加元素

            Console.WriteLine("<<<<<<<<<<<<<<<<<al中添加元素>>>>>>>>>>>>>>>>>");

            for(int i=1;i<=5;i++)

            {

                al.Add(new Point { X = i, Y = i + 2 });

            }

            PrintProperty("al", al);           

            PrintArray("al",al);

            ArrayList _getfromal = al.GetRange(1, 3);

            Console.WriteLine("使用al.GetRange(1, 3),从al1下标开始,取出3个元素,放入_getfromal");

            PrintArray("_getfromal",_getfromal);

            al.AddRange(_getfromal);

            Console.WriteLine("使用al.AddRange,将_getfromal放入中");

            PrintArray("al",al);

            Point p = new Point { X = 2, Y = 4 };

            Console.WriteLine("al中是否包含点({0}{1}{2}",p.X,p.Y,al.Contains(p));           

            al.Remove(p);

            Console.WriteLine("使用al.Remove,从al中删除({0},{1})", p.X, p.Y);

            PrintArray("al",al);

            Console.WriteLine("使用al.RemoveRange(2, 3),移除下标是2开始的3个的元素");

            al.RemoveRange(2, 3);

            PrintArray("al",al);

            Console.WriteLine("将下标是3的元素移除");

            al.RemoveAt(3);

            PrintArray("al",al);

            Console.WriteLine("使用ArrayList.FixedSize(al),得到一个具有固定大小的ArrayList");

            _getfromal = ArrayList.FixedSize(al);

            PrintProperty("_getfromal", _getfromal);

            Console.WriteLine("使用ArrayList.ReadOnly(al),得到一个具有只读的ArrayList");

            ArrayList _getReadOnly = ArrayList.ReadOnly(al);

            PrintProperty("_getReadOnly", _getReadOnly);

            Console.WriteLine("使用ArrayList.Repeat(p, 5),得到一个具有具有重复项的ArrayList");

            ArrayList repeat = ArrayList.Repeat(p, 5);

            PrintArray("repeat",repeat);

            PrintProperty("repeat", repeat);

            PrintProperty("al", al);

            Console.WriteLine("使用TrimToSize(),是的al的容量与实际数据的个数相同");

            al.TrimToSize();

            PrintProperty("al",al);

            Console.ReadKey();

        }

 

        /// <summary>

        /// 打印ArrayList的属性列表

        /// </summary>

        /// <param name="name">ArrayList对象的名字</param>

        /// <param name="al">ArrayList的集合对象</param>

        private static void PrintProperty(string name,ArrayList al)

        {

            //打印ArrayList的属性

            Console.WriteLine("<<<<<<<<<<<<<<<<打印{0}的属性列表>>>>>>>>>>>>>>>>", name);

            //打印ArrayList的容量

            Console.WriteLine("{0}的容量是:{1}",name, al.Capacity);

            //打印ArrayList中元素的个数

            Console.WriteLine("{0}中元素的个数是:{1}",name, al.Count);

            //打印ArrayList空间是否固定

            Console.WriteLine("{0}的空间固定大小?{1}",name, al.IsFixedSize);

            //打印ArrayList是否是只读的?

            Console.WriteLine("{0}是只读的吗?{1}",name, al.IsReadOnly);

        }

        /// <summary>

        /// 打印ArrayList对象的数据

        /// </summary>

        /// <param name="name">ArrayList对象的名字</param>

        /// <param name="arraylist">ArrayList的集合对象</param>

        static void PrintArray(string name,ArrayList arraylist)

        {

            Console.WriteLine("<<<<<<<<<<<<<<<<打印{0}中的元素>>>>>>>>>>>>>>>>", name);

            foreach (Object obj in arraylist)

            {

                Point p=(Point)obj;

                Console.WriteLine("({0},{1})", p.X, p.Y);

            }

        }

    }

}

注意:程序中加边框的语句,在该语句中使用了ContainsObject obj)方法来判断对象obj是否是ArrayList中的元素,因为使用了自定义的类Point的对象作为ArrayList中的元素,在调用该算法的时候,在默认的情况下,将会调用Object对象的Equals方法来判断对象是否相等,然而Object默认的Equals方法对于对象来说,比较的是两个对象是否是同一个引用,因此在自定义的类中,必须重写Equals方法,提供判断两个自定义对象是否相等的算法。否则将不会出现正确的结果。

所以类Point的代码是:

namespace ArrayListSample

{

    class Point

    {

        public int X { get; set; }

        public int Y { get; set; }

        public override bool Equals(Object p)

        {

            Point p1 = (Point)p;

            return X == p1.X && Y == p1.Y;           

        }

    }

}

程序运行的结果是:

al的容量是:0

al中元素的个数是:0

al的空间固定大小?False

al是只读的吗?False

<<<<<<<<<<<<<<<<<al中添加元素>>>>>>>>>>>>>>>>>

<<<<<<<<<<<<<<<<打印al的属性列表>>>>>>>>>>>>>>>>

al的容量是:8

al中元素的个数是:5

al的空间固定大小?False

al是只读的吗?False

<<<<<<<<<<<<<<<<打印al中的元素>>>>>>>>>>>>>>>>

(1,3)

(2,4)

(3,5)

(4,6)

(5,7)

使用al.GetRange(1, 3),从al1下标开始,取出3个元素,放入_getfromal

<<<<<<<<<<<<<<<<打印_getfromal中的元素>>>>>>>>>>>>>>>>

(2,4)

(3,5)

(4,6)

使用al.AddRange,将_getfromal放入中

<<<<<<<<<<<<<<<<打印al中的元素>>>>>>>>>>>>>>>>

(1,3)

(2,4)

(3,5)

(4,6)

(5,7)

(2,4)

(3,5)

(4,6)

al中是否包含点(24True

使用al.Remove,从al中删除(2,4)

<<<<<<<<<<<<<<<<打印al中的元素>>>>>>>>>>>>>>>>

(1,3)

(3,5)

(4,6)

(5,7)

(2,4)

(3,5)

(4,6)

使用al.RemoveRange(2, 3),移除下标是2开始的3个的元素

<<<<<<<<<<<<<<<<打印al中的元素>>>>>>>>>>>>>>>>

(1,3)

(3,5)

(3,5)

(4,6)

将下标是3的元素移除

<<<<<<<<<<<<<<<<打印al中的元素>>>>>>>>>>>>>>>>

(1,3)

(3,5)

(3,5)

使用ArrayList.FixedSize(al),得到一个具有固定大小的ArrayList

<<<<<<<<<<<<<<<<打印_getfromal的属性列表>>>>>>>>>>>>>>>>

_getfromal的容量是:8

_getfromal中元素的个数是:3

_getfromal的空间固定大小?True

_getfromal是只读的吗?False

使用ArrayList.ReadOnly(al),得到一个具有只读的ArrayList

<<<<<<<<<<<<<<<<打印_getReadOnly的属性列表>>>>>>>>>>>>>>>>

_getReadOnly的容量是:8

_getReadOnly中元素的个数是:3

_getReadOnly的空间固定大小?True

_getReadOnly是只读的吗?True

使用ArrayList.Repeat(p, 5),得到一个具有具有重复项的ArrayList

<<<<<<<<<<<<<<<<打印repeat中的元素>>>>>>>>>>>>>>>>

(2,4)

(2,4)

(2,4)

(2,4)

(2,4)

<<<<<<<<<<<<<<<<打印repeat的属性列表>>>>>>>>>>>>>>>>

repeat的容量是:5

repeat中元素的个数是:5

repeat的空间固定大小?False

repeat是只读的吗?False

<<<<<<<<<<<<<<<<打印al的属性列表>>>>>>>>>>>>>>>>

al的容量是:8

al中元素的个数是:3

al的空间固定大小?False

al是只读的吗?False

使用TrimToSize(),是的al的容量与实际数据的个数相同

<<<<<<<<<<<<<<<<打印al的属性列表>>>>>>>>>>>>>>>>

al的容量是:3

al中元素的个数是:3

al的空间固定大小?False

al是只读的吗?False

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值