一、Array数组
数组在内存中是连续的存储的,所以索引速度很快( 根据 Loc(ai)=Loc(a1)+(i-1)*w,(1<=i<=n) ,其中Loc(a1) 是基地址既第一个元素地址,i是索引数,w是存储单元,每个元素的存储单元都是相同的,所以只要知道了基地址和存储单元,就能查询到任意索引的值;例如 索引为4,查第4个值,假如w=1, Loc(4)=Loc(1)+(4-1)*1 ,既首个地址加上索引减一再乘以存储的那元就找到索引的值了,时间复杂度O(1),所以比较快),而且赋值与修改元素也很简单。可以利用地址访问元素,时间复杂度为O(1);可以用二分法查找元素、效率高。
同时,数组也有很多缺点,数组分配在一块连续的数据空间上,因此分配空间时必须确定大小。空间的连续,也导致了存储效率低,插入和删除元素效率比较低,而且麻烦。如果,要增添一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样,你想删除一个元素,需要移动大量元素去填补被移动的元素。还有我们在声明数组的时候,必须同时指明数组的长度,数组的长度过长,会造成内存浪费,数组和长度过短,会造成数据溢出的错误。这样如果在声明数组时我们并不清楚数组的长度,就变的很棘手了。
二、ArrayList动态数组 (相当于List <object>)
针对于数组的这些缺点,C#中最先提供了ArrayList对象来克服这些缺点。ArrayList是.Net Framework提供的用于数据存储和检索的专用类,它是System.Collections下的一部分。ArrayList的大小是按照其中存储的数据来动态扩充与收缩的。所以,我们在声明ArrayList对象时并不需要指定它的长度。ArrayList继承了IList接口,所以它可以很方便的进行数据的添加,插入和移除(下标会自动移动,例如移除一个元素,后面的会自动向前一位补上;插入一个元素,后面的元素下标会自动退一位(不会覆盖掉当前插入的相同下标索引)),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.Add(“123”);
IDE就会报错,且不能通过编译。这样就避免了前面讲的类型安全问题与装箱拆箱的性能问题了。
四、HashTable和Dictionary区别
4.1 HashTable
哈希表(HashTable)表示键/值对的集合。在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key-value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key-value键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对,任何非 null 对象都可以用作键或值。
在哈希表中添加一个key/键值对:HashtableObject.Add(key,);
在哈希表中去除某个key/键值对:HashtableObject.Remove(key);
从哈希表中移除所有元素: HashtableObject.Clear();
判断哈希表是否包含特定键key: HashtableObject.Contains(key);
4.2 Dictionary
Dictionary表示键和值的集合。
Dictionary<string, string>是一个泛型
他本身有集合的功能有时候可以把它看成数组
他的结构是这样的:Dictionary<[key], [value]>
他的特点是存入对象是需要与[key]值一一对应的存入该泛型
通过某一个一定的[key]去找到对应的值
4.3 HashTable和Dictionary的区别
(1).HashTable不支持泛型,而Dictionary支持泛型。
(2). Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和拆箱的操作,所以你可能需要进行一些类型转换的操作,而且对于int,float这些值类型还需要进行装箱等操作,非常耗时。
(3).单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分。多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减。
(4)在通过代码测试的时候发现key是整数型Dictionary的效率比Hashtable快,如果key是字符串型,Dictionary的效率没有Hashtable快。
原文链接:https://blog.csdn.net/weixin_40200876/article/details/88692119