一、Array数组
1.Array集合简介
- array数组的基类是System.Object ,所以为引用类型;
- array数组数据在内存中存储是连续的且长度在定义时需指定;
- array数组存储类型:同一类型;
- array数组访问形式:根据索引快速查询 如:arr[2];
2.优缺点
- 数组在内存中是连续存储的,所以他的索引访问速度非常快;(优点)
- 数组类型是一致的,存储过程中不涉及装箱拆箱(优点)
- 数组长度固定,处理非固定长度的数据比较棘手(数组长度过长,会造成内存浪费,数组长度过短,会造成数据溢出)(缺点);
- 插入效率较慢(数据是连续存储的)(缺点);
3.示例
//Array数组 Stopwatch stopWatch = new Stopwatch();//计时器:用于准确的测量运行时间 stopWatch.Start(); Console.WriteLine("开始计时初始化数组:"); int[] intArray = new int[10000000]; for (int i = 0; i < 10000000; i++) { intArray[i] = i + 1; } stopWatch.Stop(); Console.WriteLine($"初始化长度为10000000的int数组共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!");
//初始化长度为1000000的int数组共耗时:63毫秒;
二、ArrayList数组
1.ArrayList集合简介
- ArrayList是Array的升级版;
- ArrayList是.Net Framework提供的用于数据存储和检索的专用类,它是命名空间System.Collections下的一部分。
- ArrayList的大小是按照其中存储的数据来动态扩充与收缩的。
2.优缺点
- 动态扩容,声明ArrayList对象时并不需要指定它的长度,不必担心长度溢出;(优点)
- 可以存储任意数据类型;(优点)
- 查询速度快;(优点)
- 比之Array数组灵活性更强,但是在牺牲性能的基础上;
- 动态扩容的代价就是牺牲性能,ArrayList在超出默认长度后,会自动扩容;(缺点)
- 存储任意类型的代价:存取数据时会有装箱和拆箱,影响效率;(缺点)
-
ArrayList不是类型安全的
- 数据存储时不论是int还是string都当成object来处理,这样我们再使用ArrayList进行数据时很可能会报类型不匹配的问题;
- 即使保证插入数据时尽可能的保持数据类型的一致性,但在使用时也需要将它们转换为原有类型(装箱拆箱),造成性能损耗;
3.示例
//ArrayList数组 Stopwatch stopWatch = new Stopwatch();//计时器:用于准确的测量运行时间 stopWatch.Start(); Console.WriteLine("开始计时初始化ArrayList数组:"); ArrayList arrListByLength = new ArrayList(10000000);//指定数组长度 for (int i = 0; i < 10000000; i++) { arrListByLength.Add(i + 1); } stopWatch.Stop(); Console.WriteLine($"ArryList集合存储长度为10000000共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!"); stopWatch.Restart(); ArrayList arrList = new ArrayList();//不指定数组长度 for (int i = 0; i < 10000000; i++) { arrList.Add(i + 1); } stopWatch.Stop(); Console.WriteLine($"ArryList集合不指定存储长度共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!"); //ArrayList集合指定存储长度为10000000共耗时110毫秒! //ArrayList集合不指定存储长度共耗时135毫秒!
三、List数组
1.List集合简介
- List又是ArrayList的升级版,List与ArrayList都继承自IList,用法基本一样,它们最大的区别就是在声明List集合时,需要指定集合内数据的类型
2.优缺点
- 保留了Array的优点,避免了集合内数据类型不安全装箱拆箱带来的性能损耗(优点);
- 自动扩容带来的性能损耗(缺点);
3.示例
//List泛型 Stopwatch stopWatch = new Stopwatch();//计时器:用于准确的测量运行时间 stopWatch.Start(); List<int> list = new List<int>(10000000);//指定数组长度 Console.WriteLine("开始计时初始化List泛型数组:"); for (int i = 0; i < 10000000; i++) { list.Add(1 + 1); } stopWatch.Stop(); Console.WriteLine($"List泛型集合存储长度为10000000共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!"); stopWatch.Restart(); list = new List<int>();//不指定数组长度 for (int i = 0; i < 10000000; i++) { list.Add(1 + 1); } stopWatch.Stop(); Console.WriteLine($"List泛型集合不指定存储长度共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!"); //List泛型集合指定存储长度为10000000共耗时80毫秒! //List泛型集合不指定存储长度共耗时110毫秒!
四、LinkedList数组
1.LinkedList集合简介
- LinkedList采用双向链表的方式实现,在LinkedList中,每一个元素都指向下一个元素,形成一个链。
- LinkedList存储不连续;
- 支持从头部和尾部同时插入;
- 长度不固定;
2.优缺点
- 非连续存储,插入和删除效率较高;(优点)
- 长度不固定,不用考虑初始化长度;(优点)
- 支持头尾同时插入;(优点)
- 数据类型安全,创建时指定数据类型(优点)
- 查询效率低,不能通过下标访问(缺点)
3.示例
//LinkedList链表 Stopwatch stopWatch = new Stopwatch();//计时器:用于准确的测量运行时间 stopWatch.Start(); LinkedList<int> list = new LinkedList<int>();//指定数组长度 Console.WriteLine("开始计时初始化LinkedList链表数组:"); for (int i = 0; i < 10000000; i++) { list.AddFirst(1 + 1); } stopWatch.Stop(); Console.WriteLine($"LinkedList链表集合共耗时{stopWatch.ElapsedMilliseconds.ToString()}毫秒!"); //LinkedList链表集合不指定存储长度共耗时1934毫秒!
五、结论
- Array效率最高,List次之,ArrayList紧随其后,LinkedList效率最低;
- ArrayList和List,在定义时如果知道其数据长度,那么初始化时指定,效率相对比不指定长度高;