C#中数组、ArrayList和List三者的区别

来源:互联网 发布:帝国cms tags调用 编辑:程序博客网 时间:2024/05/16 15:39

一,数组

         数组在C#中最早出现的。

    * 优点:在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单。

    * 缺点:在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候必须指定数组的长度,数组的长度过长,会造成内存浪费,过短会造成数据溢出的错误。如果在声明数组时我们不清楚数组的长度,就会变得很麻烦。

     * 相关的方法

          1>一维数组的声明

                 数组类型[]数组名;    例如:int[ ]  num

          2>一维数组的创建

                 数据类型[ ]  数组名  = new 数据类型[元素个数];     例如: int [] num  = new int[10];

          3>一维数组的初始化

                *   数据类型[ ]  数组名 = new 数据类型[元素个数]{初始值列表};    例如: int [] num = new int[4]{12,34,56,78}; 

                *   数据类型[ ]  数组名 = new 数据类型[ ] {初始值列表};例如:    int[ ] num  = new int[]{1,4,7,9,10,3,6}; //省略数组大小

                *   数据类型[ ]  数组名 = {初始值列表};     例如: int [ ] num = {45,28,34,74,84};   //进一步省略new和数据类型

         4>一维数组的赋值

                 数组名 [索引值]  = 数据的值  例如:  int [] a = new int[4];   a[0] = 24;

         5>属性和方法

              *  Length   获得数组元素的个数  

              *  Rank      获得数组的秩(维数),对于一维数组来说,Rank 总是为1。  

              *  GetLength(int)   获得指定维度的元素个数。

二,ArrayList

    ArrayList是命名空间System.Collections下的一部分,在使用该类时必须进行引用,同时继承了IList接口,提供了数据存储和检索。    

    * 优点: ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的。所以,在声明ArrayList对象时并不需要指定它的长度。

    * 缺点: ArrayList中插入不同类型的数据是允许的。因为ArrayList会把所有插入其中的数据当作为object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的。在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。

     * 相关方法

               1>添加元素

                 * public virtual int Add(object value);  //将对象添加到ArrayList的结尾处

                    ArrayList aList=new ArrayList();

                     aList.Add("a");

                     aList.Add("b");

                     内容为ab

                 * public virtual void Insert(int index,object value); //将元素插入ArrayList的指定索引处

                   ArrayList aList=new ArrayList();

                     aList.Add("a");

                     aList.Add("b");

                     aList.Insert(0,"aa");

                     内容为aaab

                 * public virtual void InsertRange(int index,ICollectionc); //将集合中的某个元素插入ArrayList的指定索引处

                   ArrayList aList=new ArrayList();

                     aList.Add("a");

                     aList.Add("b");

                  ArrayList list2=new ArrayList();

                     list2.Add("tt");

                     aList.InsertRange(1,list2);

                      内容为abtt

             2>删除

                   * public virtual void Remove(object obj); //从ArrayList中移除特定对象的第一个匹配项,注意是第一个

                  ArrayList aList=new ArrayList();

                     aList.Add("a");

                     aList.Add("b");

                     aList.Remove("a");

                     内容为b

                   * public virtual void RemoveAt(int index); //移除ArrayList的指定索引处的元素

                      aList.Add("a");

                      aList.Add("b");

                      aList.RemoveAt(0);

                     内容为b

                   * public virtual void RemoveRange(int index,int count); //从ArrayList中移除一定范围的元素。Index表示索引,count表示从索引处开始的数目

                  ArrayList aList=new ArrayList();

                      aList.Add("a");

                      aList.Add("b");

                      aList.Add("c");

                      aList.Add("e");

                      aList.RemoveRange(1,2);

                      内容为ae

                    * public virtual void Clear();  //从ArrayList中移除所有元素。

              3> 排序

                    * public virtual void Sort(); //对ArrayList或它的一部分中的元素进行排序。

                      ArrayLista aList=new ArrayList();

                      aList.Add("e");

                      aList.Add("a");

                      aList.Add("b");

                      aList.Add("c");

                      aList.Add("d");

                      DropDownList1.DataSource=aList;//DropDown ListDropDownList1;

                      DropDownList1.DataBind();

                      内容为eabcd

                      ArrayList aList=new ArrayList();

                      aList.Add("a");

                      aList.Add("b");

                      aList.Add("c");

                      aList.Add("d");

                      aList.Add("e");

                      aList.Sort();//排序

                      DropDownList1.DataSource=aList;//DropDownListDropDownList1;

                      DropDownList1.DataBind();

                      内容为abcde

                    * public virtual void Reverse();  //将ArrayList或它的一部分中元素的顺序反转。

                      ArrayList aList=new ArrayList();

                       aList.Add("a");

                       aList.Add("b");

                       aList.Add("c");

                       aList.Add("d");

                       aList.Add("e");

                       aList.Reverse();//反转

                       DropDownList1.DataSource=aList;//DropDownListDropDownList1;

                       DropDownList1.DataBind();

                      内容为edcba

                4> 查找

                    * public virtual int IndexOf(object);

                    * public virtual int IndexOf(object,int);

                    * public virtual int IndexOf(object,int,int); 

                        返回ArrayList或它的一部分中某个值的第一个匹配项的从零开始的索引。没找到返回-1。

                      ArrayList aList=new ArrayList();

                      aList.Add("a");

                      aList.Add("b");

                      aList.Add("c");

                      aList.Add("d");

                      aList.Add("e");

                      int nIndex=aList.IndexOf(“a”);//1

                      nIndex=aList.IndexOf(“p”);//没找到,-1

                    * public virtual int LastIndexOf(object);

                    * public virtual int LastIndexOf(object,int);

                    * public virtual int LastIndexOf(object,int,int);

                        返回ArrayList或它的一部分中某个值的最后一个匹配项的从零开始的索引。

                     ArrayList aList=new ArrayList();

                     aList.Add("a");

                     aList.Add("b");

                     aList.Add("a");//同0

                     aList.Add("d");

                     aList.Add("e");

                     int nIndex=aList.LastIndexOf("a");//值为2而不是0

                    * public virtual bool Contains(object item);

                       确定某个元素是否在ArrayList中。包含返回true,否则返回false

                 5>获取数组中的元素

                      ArrayList aList=new ArrayList();

                        for(int i=0;i<10;i++)

                           aList.Add(i);

                        for(i=0;i<10;i++)

                        Textbox1.text+=(int)aList[i]+" ";//获取的方式基本与一般的数组相同,使用下标的方式进行

                        结果为:0 1 2 3 4 5 6 7 8 9

                 6>其他

                    * public virtual int Capacity{get;set;} //获取或设置ArrayList可包含的元素数。

                    * public virtual int Count{get;} //获取ArrayList中实际包含的元素数。

                       Capacity是ArrayList可以存储的元素数。

                       Count是ArrayList中实际包含的元素数。

                       Capacity总是大于或等于Count。如果在添加元素时,Count超过Capacity,则该列表的容量会通过自动重新分配内部数组加倍。

                       如果Capacity的值显式设置,  则内部数组也需要重新分配以容纳指定的容量。

                       如果Capacity被显式设置为0,则公共语言运行库将其设置为默认容量。默认容量为16。

                  注意:在调用Clear后,Count为0,而此时Capacity却是默认容量16,而不是0

                    * public virtual void TrimToSize();  //将容量设置为ArrayList中元素的实际数量。

                     如果不向列表中添加新元素,则此方法可用于最小化列表的内存系统开销。

                     若要完全清除列表中的所有元素,请在调用TrimToSize之前调用Clear方法。

                      截去空ArrayList会将ArrayList的容量设置为默认容量,而不是零。

                       ArrayList aList=new ArrayList();

                        aList.Add("a");

                        aList.Add("b");

                        aList.Add("c");

                        aList.Add("d");

                        aList.Add("e");//Count=5,Capacity=16,

                        aList.TrimToSize();//Count=Capacity=5;


 *   装箱与拆箱的概念:
    1> 
装箱:就是将值类型的数据打包到引用类型的实例中
       
比如将string类型的值abc赋给object对象obj

          String  i=”abc”;  

          object obj=(object)i;  

     2> 拆箱:就是从引用数据中提取值类型
       
比如将object对象obj的值赋给string类型的变量i

          object obj=”abc”;  

          string i=(string)obj; 

    装箱与拆箱的过程是很损耗性能的。

三,泛型List

     因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。

  * 优点:避免了前面讲的类型安全问题与装箱拆箱的性能问题了

  * 缺点: 在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。

  * 相关方法

     List一般方法

      1>  声明: 

          * List<T> mList = new List<T>();   //T为列表中元素类型,现在以string类型作为例子

           List<string> mList = new List<string>();


          * List<T> testList =new List<T> (IEnumerable<T> collection); //以一个集合作为参数创建List

            string[] temArr = { "Ha", "Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", "Locu" };

            List<string> testList = new List<string>(temArr);

     2>添加元素:

         * List. Add(T item)  添加一个元素

            mList.Add("John");

       * List. AddRange(IEnumerable<T> collection)  添加一组元素

           string[] temArr = { "Ha","Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku",  "Locu" };

           mList.AddRange(temArr);

       *  Insert(int index, T item);   index位置添加一个元素

           mList.Insert(1, "Hei");

     3> 遍历List中元素:

          foreach (T element in mList)  T的类型与mList声明时一样

         {

               Console.WriteLine(element);

         }


         foreach (string s in mList)

         {

              Console.WriteLine(s);

         }

     4>删除元素:

       *  List. Remove(T item)删除一个值

           mList.Remove("Hunter");

       * List. RemoveAt(int index);  删除下标为index的元素

           mList.RemoveAt(0);

       * List. RemoveRange(int index, int count);从下标index开始,删除count个元素

           mList.RemoveRange(3, 2);

     5>判断某个元素是否在该List中:

       * List. Contains(T item)  返回truefalse,很实用

         if (mList.Contains("Hunter"))

         {

             Console.WriteLine("There is Hunter in the list");

          }else{

            mList.Add("Hunter");

            Console.WriteLine("Add Hunter successfully.");

          }

     6>给List里面元素排序及反转:

        * List. Sort ()  默认是元素第一个字母按升序

            mList.Sort();

         *  List. Reverse ()  List里面元素顺序反转:

            mList.Sort();

      7>List清空:List. Clear () 

            mList.Clear();

     8>获得List中元素数目:

           List. Count ()    返回int

           int count = mList.Count();

           Console.WriteLine("The num of elements in the list: " +count);

     List的进阶方法:

      举例用的List

        string[] temArr = { Ha","Hunter", "Tom", "Lily", "Jay", "Jim", "Kuku", " "Locu" };

        mList.AddRange(temArr);

        1> List.Find 方法:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的第一个匹配元素。 

            public T Find(Predicate<T> match);

             Predicate是对方法的委托,如果传递给它的对象与委托中定义的条件匹配,则该方法返回 true。当前 List的元素被逐个传递给Predicate委托,并在 List 中向  前移动,从第一个元素开始,到最后一个元素结束。当找到匹配项时处理即停止。

            Predicate可以委托给一个函数或者一个拉姆达表达式:

         委托给拉姆达表达式:

          string listFind = mList.Find(name =>  //name是变量,代表的是mList

          {      //中元素,自己设定

            if (name.Length > 3){

             return true;

          }

           return false;  });

         Console.WriteLine(listFind);     //输出是Hunter

        委托给一个函数:

          string listFind1 = mList.Find(ListFind);  //委托给ListFind函数

          Console.WriteLine(listFind);    //输出是Hunter

       ListFind函数: 

          public bool ListFind(string name)

          {

           if (name.Length > 3)

          {

          return true;

         }

          return false;

        }

     这两种方法的结果是一样的。

2> List.FindLast 方法:搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List 中的最后一个匹配元素。 

      public T FindLast(Predicate<T> match);

     用法与List.Find相同。

3> List.TrueForAll方法: 确定是否 List 中的每个元素都与指定的谓词所定义的条件相匹配。

      public bool TrueForAll(Predicate<T> match);

     委托给拉姆达表达式:

      bool flag = mList.TrueForAll(name =>

     {

     if (name.Length > 3) {

          return true;

     }else{

          return false;

    } });

     Console.WriteLine("True for all:  "+flag);  //flag值为false

    委托给一个函数,这里用到上面的ListFind函数:

     bool flag = mList.TrueForAll(ListFind); //委托给ListFind函数

     Console.WriteLine("True for all:  "+flag);  //flag值为false

   这两种方法的结果是一样的。

4> List.FindAll方法:检索与指定谓词所定义的条件相匹配的所有元素。

     public List<T> FindAll(Predicate<T> match);

     List<string> subList = mList.FindAll(ListFind); //委托给ListFind函数

     foreach (string s in subList)

     {

    Console.WriteLine("element in subList: "+s);

     }

    这时subList存储的就是所有长度大于3的元素

5> List.Take(n) 获得前n 返回值为IEnumetable<T>T的类型与List<T>的类型一样

    IEnumerable<string> takeList=  mList.Take(5);

     foreach (string s in takeList)

    {

      Console.WriteLine("element in takeList: " + s);

     }

    这时takeList存放的元素就是mList中的前5

    List.Where方法:检索与指定谓词所定义的条件相匹配的所有元素。跟List.FindAll方法类似。

    IEnumerable<string> whereList = mList.Where(name =>

     {

       if (name.Length > 3){

          return true;

       }else{

          return false;

     }});

    foreach (string s in subList){

       Console.WriteLine("element in subList: "+s);

    }

   这时subList存储的就是所有长度大于3的元素

    6> List.RemoveAll方法:移除与指定的谓词所定义的条件相匹配的所有元素。

        public int RemoveAll(Predicate<T> match);

        mList.RemoveAll(name => {

        if (name.Length > 3){

            return true;

        }else{

           return false;

       }

       });

       foreach (string s in mList){

         Console.WriteLine("element in mList:     " + s);

       }

      这时mList存储的就是移除长度大于3之后的元素。

四,总结

     数组的容量是固定的,您只能一次获取或设置一个元素的值,而ArrayListList<T>的容量可根据需要自动扩充、修改、删除或插入数据。

     数组可以具有多个维度,而 ArrayList List< T>始终只具有一个维度。但是,您可以轻松创建数组列表或列表的列表。特定类型(Object 除外)的数组的性能优于 ArrayList的性能。 这是因为 ArrayList的元素属于 Object类型;所以在存储或检索值类型时通常发生装箱和取消装箱操作。不过,在不需要重新分配时(即最初的容量十分接近列表的最大容量),List< T>的性能与同类型的数组十分相近。

    在决定使用 List<T>还是使用ArrayList 类(两者具有类似的功能)时,记住List<T>类在大多数情况下执行得更好并且是类型安全的。如果对List< T> 类的类型T使用引用类型,则两个类的行为是完全相同的。但是,如果对类型T使用值类型,则需要考虑实现和装箱问题。

0 0
原创粉丝点击