欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中数组Array,ArrayList,泛型List详细对比

程序员文章站 2023-11-14 08:08:34
在c#中数组array,arraylist,泛型list都能够存储一组对象,但是在开发中根本不知道用哪个性能最高,下面我们慢慢分析分析。 一、数组array 数组是...

在c#中数组array,arraylist,泛型list都能够存储一组对象,但是在开发中根本不知道用哪个性能最高,下面我们慢慢分析分析。

一、数组array

数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。

array 类是 c# 中所有数组的基类,它是在 system 命名空间中定义。

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

array数组具体用法:

using system;

namespace webapp
{
  class program
  {
    static void main(string[] args)
    {
      //system.array
      //1、数组[] 特定类型、固定长度
      string[] str1 = new string[3];
      str1[0] = "a";
      str1[1] = "b";
      str1[2] = "c";
      console.writeline(str1[2]);

      string[] str2 = new string[] { "a", "b", "c" };
      console.writeline(str2[0]);

      string[] str3 = { "a", "b", "c" };
      console.writeline(str3[0]);
      //2、二维数组
      //int[,] intarray=new int[2,3]{{1,11,111},{2,22,222}};
      int[,] intarray = new int[2, 3];
      intarray[0, 0] = 1;
      intarray[0, 1] = 11;
      intarray[0, 2] = 111;

      intarray[1, 0] = 2;
      intarray[1, 1] = 22;
      intarray[1, 2] = 222;
      console.writeline("{0},{1},{2}", intarray[0, 0], intarray[0, 1], intarray[0, 2]);
      console.writeline("{0},{1},{2}", intarray[1, 0], intarray[1, 1], intarray[1, 2]);

      //3、多维数组
      int[, ,] intarray1 = new int[,,]
      {
        {{1, 1}, {11, 11}, {111, 111}},
        {{2, 2}, {22, 22}, {222, 222}},
        {{3, 3}, {33, 33}, {333, 333}}
      };
      console.writeline("{0},{1},{2},{3},{4},{5}", intarray1[0, 0, 0], intarray1[0, 0, 1], intarray1[0, 1, 0], intarray1[0, 1, 1],
        intarray1[0, 2, 0], intarray1[0, 2, 1]);
      console.writeline("{0},{1},{2},{3},{4},{5}", intarray1[1, 0, 0], intarray1[1, 0, 1], intarray1[1, 1, 0], intarray1[1, 1, 1],
        intarray1[1, 2, 0], intarray1[1, 2, 1]);
      console.writeline("{0},{1},{2},{3},{4},{5}", intarray1[2, 0, 0], intarray1[2, 0, 1], intarray1[2, 1, 0], intarray1[2, 1, 1],
        intarray1[2, 2, 0], intarray1[2, 2, 1]);

      //4、交错数组即数组的数组
      int[][] intarray2 = new int[4][];
      intarray2[0] = new int[] { 1 };
      intarray2[1] = new int[] { 2, 22 };
      intarray2[2] = new int[] { 3, 33, 333 };
      intarray2[3] = new int[] { 4, 44, 444,4444 };
      for (int i = 0; i < intarray2.length; i++)
      {
        for (int j = 0; j < intarray2[i].length; j++)
        {
          console.writeline("{0}", intarray2[i][j]);
        }
      }


      console.readkey();
    }
  }
}

数组虽然存储检索数据很快,但是也有一些缺点:

1、在声明数组的时候必须指定数组的长度,如果不清楚数组的长度,就会变得很麻烦。

2、数组的长度太长,会造成内存浪费;太短会造成数据溢出的错误。

3、在数组的两个数据间插入数据是很麻烦的

更多参考微软官方文档:array 类 (system)

二、arraylist

既然数组有很多缺点,c#就提供了arraylist对象来克服这些缺点。

arraylist是在命名空间system.collections下,在使用该类时必须进行引用,同时继承了ilist接口,提供了数据存储和检索。

arraylist对象的大小是按照其中存储的数据来动态扩充与收缩的。因此在声明arraylist对象时并不需要指定它的长度。

arraylist 的默认初始容量为 0。随着元素添加到 arraylist 中,容量会根据需要通过重新分配自动增加。可通过调用 trimtosize 或通过显式设置 capacity 属性减少容量。

using system;
using system.collections;
public class samplesarraylist {

  public static void main() {

   arraylist myal = new arraylist();
   myal.add("hello");
   myal.add("world");
   myal.add("!");

   console.writeline( "myal" );
   console.writeline( "  count:  {0}", myal.count );
   console.writeline( "  capacity: {0}", myal.capacity );
   console.write( "  values:" );
   printvalues( myal );
  }

  public static void printvalues( ienumerable mylist ) {
   foreach ( object obj in mylist )
     console.write( "  {0}", obj );
   console.writeline();
   console.readkey();
  }

}

运行结果:

arraylist解决了数组中所有的缺点,但是在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。尤其是装箱操作,例如:

      arraylist list = new arraylist();

      //add 
      list.add("joye.net");
      list.add(27);

      //update 
      list[2] = 28;

      //delete 
      list.removeat(0);

      //insert 
      list.insert(0, "joye.net1"); 

在list中,先插入了字符串joye.net,而且插入了int类型27。这样在arraylist中插入不同类型的数据是允许的。因为arraylist会把所有插入其中的数据当作为object类型来处理,在使用arraylist处理数据时,很可能会报类型不匹配的错误,也就是arraylist不是类型安全的。

更多参考微软官方arraylist文档:arraylist 类 (system.collections)

三、泛型list<t>

由于arraylist存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。

list 类是 arraylist 类的泛型等效类。该类使用大小可按需动态增加的数组实现 ilist 泛型接口,大部分用法都与arraylist相似。

list<t> 是类型安全的,在声明list集合时,必须为其声明list集合内数据的对象类型。

using system;
using system.collections.generic;

public class example
{
  public static void main()
  {
    list<string> dinosaurs = new list<string>();

    console.writeline("\ncapacity: {0}", dinosaurs.capacity);

    dinosaurs.add("tyrannosaurus");
    dinosaurs.add("amargasaurus");
    dinosaurs.add("mamenchisaurus");
    dinosaurs.add("deinonychus");
    dinosaurs.add("compsognathus");

    console.writeline();
    foreach(string dinosaur in dinosaurs)
    {
      console.writeline(dinosaur);
    }

    console.writeline("\ncapacity: {0}", dinosaurs.capacity);
    console.writeline("count: {0}", dinosaurs.count);

    console.writeline("\ncontains(\"deinonychus\"): {0}",
      dinosaurs.contains("deinonychus"));

    console.writeline("\ninsert(2, \"compsognathus\")");
    dinosaurs.insert(2, "compsognathus");

    console.writeline();
    foreach(string dinosaur in dinosaurs)
    {
      console.writeline(dinosaur);
    }

    console.writeline("\ndinosaurs[3]: {0}", dinosaurs[3]);

    console.writeline("\nremove(\"compsognathus\")");
    dinosaurs.remove("compsognathus");

    console.writeline();
    foreach(string dinosaur in dinosaurs)
    {
      console.writeline(dinosaur);
    }

    dinosaurs.trimexcess();
    console.writeline("\ntrimexcess()");
    console.writeline("capacity: {0}", dinosaurs.capacity);
    console.writeline("count: {0}", dinosaurs.count);

    dinosaurs.clear();
    console.writeline("\nclear()");
    console.writeline("capacity: {0}", dinosaurs.capacity);
    console.writeline("count: {0}", dinosaurs.count);
  }
}

如果声明list集合内数据的对象类型是string,然后往list集合中插入int类型的111,ide就会报错,且不能通过编译。显然这样list<t>是类型安全的。

对返回结果集再封装:

  public class resultdto<t>
  {
    public t data { get; set; }
    public string code { get; set; }
    public string message { get; set; }
  }

      var data = new cityentity();
      return new resultdto<cityentity> { data = data, code = "1", message = "sucess"};

      var data2 = new list<cityentity>();
      return new resultdto<list<cityentity>> { data = data2, code = "1", message = "sucess" };

      var data1 = 1;
      return new resultdto<int> { data = data1, code = "1", message = "sucess" };

更多参考微软官方文档:list泛型类

四、总结

1、数组的容量固定,而arraylist或list<t>的容量可根据需要自动扩充。

2、数组可有多个维度,而 arraylist或 list< t> 始终只有一个维度。(可以创建数组列表或列表的列表)

3、特定类型的数组性能优于 arraylist的性能(不包括object,因为 arraylist的元素是 object ,在存储或检索值类型时通常发生装箱和取消装箱操作)。

4、 arraylist 和 list<t>基本等效,如果list< t> 类的类型t是引用类型,则两个类的行为是完全相同的。如果t是值类型,需要考虑装箱和拆箱造成的性能损耗。list<t> 是类型安全。