zoukankan      html  css  js  c++  java
  • C#中数组、ArrayList和List三者的区别

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

     

    [引用BobWei的blog:https://www.cnblogs.com/BObwei/p/4869157.html]

     

    在C#中,ArrayList,List都能够存储一组对象,那么这三者到底有什么样的区别呢。

    数组

       数组在C#中是最早出现的。它在内存中是连续的存储的,所以索引速度很快,而且赋值与修改元素也很简单。可以利用偏移地址访问元素,时间复杂度为O(1);可以用折半查找法查找元素,效率高。

      

    复制代码
    复制代码
    string[] s=new string[3];
    
    //赋值
    s[0]="a";
    s[1]="b";
    s[2]="c";
    
    //修改
    s[1]="b1";
    复制代码
    复制代码

    同时,数组也有很多缺点。数组分配在一块连续的数据空间上,因此分配空间时必须确定大小。空间的连续,也导致了存储效率低,插入和删除元素效率比较低,而且麻烦。如果,要增添一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样,你想删除一个元素,需要移动大量元素去填补被移动的元素。

    还有我们在声明数组的时候,必须同时指明数组的长度,数组的长度过长,会造成内存浪费,数组和长度过短,会造成数据溢出的错误。这样如果在声明数组时我们并不清楚数组的长度,就变的很棘手了。

    针对于数组的这些缺点,C#中最先提供了ArrayList对象来克服这些缺点。

    ArrayList

    ArrayList是.Net Framework提供的用于数据存储和检索的专用类,它是命名空间System.Collections下的一部分。它的大小是按照其中存储的数据来动态扩充与收缩的。所以,我们在声明ArrayList对象时并不需要指定它的长度。

    ArrayList继承了IList接口,所以它可以很方便的进行数据的添加,插入和移除.比如:

    复制代码
    复制代码
    ArrayList list = new ArrayList();
    
    //新增数据
    list.Add("abc");
    list.Add(123);
    
    //修改数据
    list[2] = 345;
    
    //移除数据
    list.RemoveAt(0);
    
    //插入数据
    list.Insert(0, "hello world");
    
    获取元素值
    object value = al[index]; //al 为 ArrayList 对象,一般需要再对 value 进行类型转换,比如:int n = (int)value;
    设置元素值
    al[index] = value; //al 为 ArrayList 对象,index 必须小于 Count
    追加元素
    int ArrayList.Add(object value) //返回添加的元素的索引
    插入元素
    void ArrayList.Insert(int index, object value)
    删除元素
    删除元素后,后面的元素会前移,但 Capacity 不会变化。
    void ArrayList.Remove(object obj) //从前(索引 0)往后查找,删除找到的第一个和 obj 相同的元素
    void ArrayList.RemoveAt(int index) //删除索引 index 对应的元素
    void ArrayList.RemoveRange(int index, int count) //从索引 index 开始,删除 count 个元素
    查找元素
    int ArrayList.IndexOf(object value) //从前(索引 0)往后查找,返回找到的第一个和 obj 相同的元素的索引
    int ArrayList.IndexOf(object value, int startIndex)
    int ArrayList.IndexOf(object value, int startIndex, int count)
    int ArrayList.LastIndexOf(object value) //从后往前(索引 0)查找,返回找到的第一个和 obj 相同的元素的索引
    int ArrayList.LastIndexOf(object value, int startIndex)
    int ArrayList.LastIndexOf(object value, int startIndex, int count)
    复制代码
    复制代码

    从上面示例看,ArrayList好像是解决了数组中所有的缺点,那么它应该就是完美的了,为什么在C#2.0后又会出现List呢?

    还是从上面的示例看,在list中,我们不仅插入了字符串"abc",而且又插入了数字123。这样在ArrayList中插入不同类型的数据是允许的。因为ArrayList会把所有插入其中的数据都当作为object类型来处理。这样,在我们使用ArrayList中的数据来处理问题的时候,很可能会报类型不匹配的错误,也就是说ArrayList不是类型安全的。既使我们保证在插入数据的时候都很小心,都有插入了同一类型的数据,但在使用的时候,我们也需要将它们转化为对应的原类型来处理。这就存在了装箱与拆箱的操作,会带来很大的性能损耗。

    穿插一下装箱与拆箱的概念:

    简单的来讲:

    装箱:就是将值类型的数据打包到引用类型的实例中

    比如将int类型的值123赋给object对象o

    int i=123;
    object o=(object)i;

    拆箱:就是从引用数据中提取值类型

    比如将object对象o的值赋给int类型的变量i

    object o=123;
    int i=(int)o;

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

    泛型List

    正是因为ArrayList存在不安全类型与装箱拆箱的缺点,所以在C#2.0后出现了泛型的概念。而List类是ArrayList类的泛型等效类。它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。

    复制代码
    复制代码
    List<int> list = new List<int>();
    //新增数据
    list.Add(123);
    //修改数据
    list[0] = 345;
    //移除数据
    list.RemoveAt(0);
    复制代码
    复制代码

    上例中,如果我们往List集合中插入string字符"hello world",IDE就会报错,且不能通过编译。这样就避免了前面讲的类型安全问题与装箱拆箱的性能问题了。

    复制代码
    复制代码
    Console.WriteLine("List Test:"); 
    //声明一个整型的List 
    List<int> lsTest = new List<int>(); 
    lsTest.Add(7); 
    lsTest.Add(5); 
    lsTest.Add(1); 
    lsTest.Add(3); 
    string strTest=""; 
    //list的排序 
    lsTest.Sort(); 
    //list的遍历 
    foreach(int i in lsTest) 
    strTest+=i.ToString()+" "; 
    //格式化后输出 
    Console.Write(string.Format("Out:{0} nCount:{1}n",strTest,lsTest.Count)); 
    //读取下一个按键,以便让屏幕显示数据 
    Console.ReadKey();
    复制代码
    复制代码

    出结果如下

    程序代码
    List Test: 
    Out:1 3 5 7 
    Count:4
  • 相关阅读:
    常用知识点集合
    LeetCode 66 Plus One
    LeetCode 88 Merge Sorted Array
    LeetCode 27 Remove Element
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 448 Find All Numbers Disappeared in an Array
    LeetCode 219 Contains Duplicate II
    LeetCode 118 Pascal's Triangle
    LeetCode 119 Pascal's Triangle II
    LeetCode 1 Two Sum
  • 原文地址:https://www.cnblogs.com/djx123/p/15492044.html
Copyright © 2011-2022 走看看