• [转]C# 数组、ArrayList、List、Dictionary的用法与区别


    前言

      在工作中经常遇到C#数组、ArrayList、List、Dictionary存取数据,但是该选择哪种类型进行存储数据,对于初学者的我一直不知道该怎么取舍。于是抽空好好看了下他们的用法和比较,在这里总结下来,后面有需要改进的再更新。

    初始化

    数组:

    int[] buff = new int[6];

    ArrayList:

    ArrayList buff = new ArrayList();

    List:

    List<int> buff = new List<int>();

    Dictionary:

    Dictionary<int,string> buff = new Dictionary<int,string>;

    分析比较

      从上面初始化的几种类型可以看出,他们都属于引用类型。其中数组、List、Dictionary在初始化的时候需要指定其元素类型,而ArrayList不需要指定类型。而在其中只有数组在初始化时设置了其大小。

      数组:在初始化时必须指定其大小和类型,他在内存中是连续存储的,所以可以看出数组的索引速度是非常快的。在确定了数组的长度和类型后,选择数组存储数据是比较好的选择。不适合插入操作。

      ArrayList:在初始化的时候不需要指定其大小和类型。他可以存储不同的数据类型,但是在存取得过程中会引起装箱和拆箱,降低了性能。插入操作方便。

      List:在初始化的时候必须指定其类型,但是不需要指定大小,所以他不会像ArraryList那样在存取过程中引起装箱和拆箱操作。在类型相同的情况下,List和数组的性能相当。插入操作方便。

      Dictionary:在初始化的时候也必须指定其类型,而且他还需要指定一个Key,并且这个Key是唯一的。正因为这样,Dictionary的索引速度非常快。但是也因为他增加了一个Key,Dictionary占用的内存空间比其他类型要大。他是通过Key来查找元素的,元素的顺序是不定的。

    类型 确定大小 确定类型 索引速度 性能
    数组 Y Y 很快 最高
    ArrayList N N 一般
    List N Y 很快
    Dictionary N Y 最快 一般

    注:以上内容如有描述不妥,请留言,分享知识,共成长!


    ---------------------
    作者:sunny123456
    来源:CNBLOGS
    原文:https://www.cnblogs.com/sunny3158/p/12215396.html

    在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求。

    由于这种限制不方便,所以出现了ArrayList。

    ArrayList、List<T>
    ArrayList是可变长数组,你可以将任意多的数据Add到ArrayList里面。其内部维护的数组,当长度不足时,会自动扩容为原来的两倍。

    但是ArrayList也有一个缺点,就是存入ArrayList里面的数据都是Object类型的,所以如果将值类型存入和取出的时候会发生装箱、拆箱操作(就是值类型与引用类型之间的转换),这个会影响程序性能。在.Net 2.0泛型出现以后,就提供了List<T>。

    List<T>是ArrayList的泛型版本,它不再需要装箱拆箱,直接取,直接用,它基本与ArrayList一致,不过在使用的时候要先设置好它的类型,而设置好类型之后,不是这种类型的数据,是不允许Add进去的。

    就性能来说,如果要存进数组的只有一种数据,那么无疑List<T>是最优选择。

    List<int> ListInt = new List<int>();
    如果一个变长数组,又要存int,又要存string。那么就只能用ArrayList。

    HashTable(哈希表)、Dictionary<T,T>
    HashTable是一种根据key查找非常快的键值数据结构,不能有重复key,而且由于其特点,其长度总是一个素数,所以扩容后容量会比2倍大一点点,加载因子为0.72f。

    当要大量使用key来查找value的时候,HashTable无疑是最有选择,HashTable与ArrayList一样,是非泛型的,value存进去是object,存取会发生装箱、拆箱,所以出现了Dictionary<T,T>。

    Dictionary<T,T>是HashTable的泛型版本,存取同样快,但是不需要装箱和拆箱了。而且,其优化了算法,Hashtable是0.72,它的浪费容量少了很多。

    Dictionary<string,Person> Dic = new Dictionary<string,Person>();
    HashSet<T>
    HashSet<T>类,算法,存储结构都与哈希表相同,主要是设计用来做高性能集运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现且无特定顺序的元素。

    Queue、Queue<T>
    Queue队列,Queue<T>泛型队列,大学都学过,队列,先进先出,很有用。

    Stack、Stack<T>
    Stack堆栈,先进后出。

    SortedList、SortedList<TKey,TValue>
    SortedList集合中的数据是有序的。可以通过key来匹配数据,也可以通过int下标来获取数据。

    添加操作比ArrayList,Hashtable略慢;查找、删除操作比ArrayList快,比Hashtable慢。

    SortedDictionary<TKey,TValue>
    SortedDictionary<TKey,TValue>相比于SortedList<TKey,TValue>其性能优化了,SortedList<TKey,TValue>其内部维护的是数组而SortedDictionary<TKey,TValue>内部维护的是红黑树(平衡二叉树)的一种,因此其占用的内存,性能都好于SortedDictionary<TKey,TValue>。唯一差在不能用下标取值。

    ListDictionary(单向链表),LinkedList<T>(双向链表)
    List<T>,ArrayList,Hashtable等容器类,其内部维护的是数组Array来,ListDictionary和LinkedList<T>不用Array,而是用链表的形式来保存。链表最大的好处就是节约内存空间。

    ListDictionary是单向链表。

    LinkedList<T>双向链表。双向链表的优势,可以插入到任意位置。

    HybridDictionary
    HybridDictionary的类,充分利用了Hashtable查询效率高和ListDictionary占用内存空间少的优点,内置了Hashtable和ListDictionary两个容器,添加数据时内部逻辑如下:

    当数据量小于8时,Hashtable为null,用ListDictionary保存数据。

    当数据量大于8时,实例化Hashtable,数据转移到Hashtable中,然后将ListDictionary置为null。

    BitArray
    BitArray这个东东是用于二进制运算,"或"、"非"、"与"、"异或非"等这种操作,只能存true或false;

    应用场景
    ArrayList,List<T>:变长数组;

    HashTable,Dictionary<T,T>:频繁根据key查找value;

    HashSet<T>:集合运算;

    Queue、Queue<T>:先进先出;

    Stack、Stack<T>:堆栈,先进先出;

    SortedList、SortedList<TKey,TValue>:哈希表,要通过下标,又要通过key取值时,可选用;

    ListDictionary:单向链表,每次添加数据时都要遍历链表,数据量大时效率较低,数据量较大且插入频繁的情况下,不宜选用。

    LinkedList<T>:双向链表;

    HybridDictionary:未知数据量大小时,可用。

    SortedDictionary<TKey,TValue>:SortedList<TKey,TValue>的优化版,内部数组转平衡二叉树。

    BitArray:二进制运算时可选用;

  • 相关阅读:
    完整的WSDL语法
    WSDL UDDI
    八一八 The Social Network的小细节
    MySQL命令行常用命令
    AspectJ风格的Aop切点表达式
    强大的Mockito测试框架
    MySQL锁定状态查看命令
    Yum本地Rpm库设置
    Sed实例大全
    为何 Emacs 和 Vim 被称为两大神器
  • 原文地址:https://www.cnblogs.com/kevinl/p/14952824.html
Copyright © 2020-2023  润新知