C#容器类,性能介绍
http://www.php.cn/csharp-article-354819.html
1 indexer
[]声明的变量必须是固定长度的,即长度是静态的;object[] objectArray = new object[10];
objectArray是浅复制,即只在memory中给其赋一个地址值,此时每一item此时都是null引用;
应用举例
1
2
3
4
5
6
7
8
|
AdjustablePanel[] adjustPanelArrays = new AdjustablePanel[12]; foreach (Control ultraControl in this .Controls) { if (ultraControl.GetType() == typeof (UltraGrid) || ultraControl.GetType() == typeof (UltraChart) || ultraControl.GetType() == typeof (Panel)) { //adjustPanelArrays[index]此时为null,因此会出现null引用bug adjustPanelArrays[index].Controls.Add(ultraControl); } } |
2 Array
提供创建、操作、搜索和排序数组的方法,因而在公共语言运行时用作所有数组的基类。长度是固定的,不能按需动态增加;Array 是抽象类,不能使用 new Array 创建;GetValue返回的是object类型。
1
2
3
4
5
|
Array myArray = Array.CreateInstance( typeof ( int ),3); myArray.SetValue(1,0); myArray.SetValue(2,1); myArray.SetValue(3,2); //GetValue返回的是object类型,需要进行类型提升为int int val2 = ( int )myArray.GetValue(2); |
3 ArrayList
使用大小可按需动态增加的数组实现 IList 接口,且是针对任意类型。
1
2
3
4
5
6
7
8
|
ArrayList al = new ArrayList(); ArrayList arrayList = new ArrayList(); al.Add( "qaz" ); al.Add(1); al.Add( new List< object >()); string str = ( string )al[0]; int intval = ( int )al[1]; List< object > objs = (List< object >)al[2]; |
总结
[], Array 编译前需要已知长度,是静态的,类型需要唯一确定的,Array是抽象类,创建需要Array.CreateInstance();
ArrayList 编译时长度未知,是动态的,并且添加的元素可以是不同的类型。
4 List-APIs
4-1 简介
List< T>是一个泛型类,实现了接口IList< T>,通过内部使用一个size动态调整的数组来显示外部的接口。
4-2 增加元素
实现添加一个元素
1
|
Add(obj) |
批量添加元素到列表中:
1
|
AddRange(objList) |
举例:
1
2
3
4
5
|
private List< int > intList = new List< int >(); public void AddApi() { intList.Add(10); //添加1个元素 intList.AddRange( new List< int >() { 5, 1, 1, 2, 2, 3 }); //批量添加元素 } |
将集合中的某个元素插入指定索引处
1
|
void Insert( int index, T item); |
1
|
void InsertRange( int index, IEnumerable《T》 collection) |
4-3移除元素
假定intList是一个List类型,初始值为 {10,5,1,1,2,2,3}。执行:
1
|
intList.Remove(1); |
从intList中移除特定对象的第一个匹配项。移除元素1后,intList = {10,5,1,2,2,3};
移除一定范围的元素 :
1
|
intList.RemoveRange(0, 2); |
intList = {2,2,3};
移除所有重复元素后:intList = {3};
1
2
3
4
|
intList.RemoveAll(removeDuplicateElements); intList.RemoveAll(i => { List< int > elementList = intList.FindAll(r => r.Equals(i)); if (elementList != null && elementList.Count > 1) return true ; return false ; }); |
在以上判断某个元素是否存在时,比如移除某个元素时,需要用到相等比较器。如果类型T实现了IEquatable< T> 泛型接口,相等比较器就是 Equals(T) 方法; 否则, 默认的相等比较器是 Object.Equals(Object).
下面看一个不是默认的比较器,实现接口的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class MyObject { public int Value { get ; set ; } public MyObject( int value) { this .Value = value; } } //实现接口IEquatable<MyObject> public class MyObjectCollection : IEquatable<MyObject> { private List<MyObject> _myObjects = new List<MyObject>() { new MyObject(3), new MyObject(4), new MyObject(3), new MyObject(2), new MyObject(3) }; //删除所有重复的元素 public void RemoveDuplicates() { _myObjects.RemoveAll(Equals); } public List<MyObject> MyObjects { get { return _myObjects; } } public bool Equals(MyObject other) { MyObject duplicate = _myObjects.Find(r => r.Value == other.Value); if (duplicate != null && duplicate!=other) return true ; return false ; } } |
此处实现了Equals(object),但是Remove(test)暂时是失败的,以后找原因。
4-4查找元素
确定某元素是否在List 中。
1
|
bool Contains(obj) |
确定是否包含与指定谓词所定义的条件相匹配的元素。
1
|
bool Exists(Predicate<T> match) |
搜索与指定谓词所定义的条件相匹配的元素,并返回第一个匹配元素。
1
|
T Find(Predicate<T> match) |
检索与指定谓词定义的条件匹配的所有元素。
1
|
List<T> FindAll(Predicate<T> match) |
搜索与指定谓词所定义的条件相匹配的元素,并返回第一个匹配元素的从零开始的索引
1
|
int FindIndex(Predicate<T> match) |
搜索与指定谓词所定义的条件相匹配的元素,并返回从指定索引到最后一个元素的元素范围内第一个匹配项的从零开始的索引。
1
|
int FindIndex( int startIndex, Predicate<T> match) |
搜索与指定谓词所定义的条件相匹配的元素,并返回从指定的索引开始并包含指定元素数量的元素范围内的第一个匹配项的零始索引
1
|
int FindIndex( int startIndex, int count, Predicate<T> match) |
1
|
T FindLast(Predicate<T> match) |
1
|
int FindLastIndex(Predicate<T> match) |
1
|
int FindLastIndex( int startIndex, Predicate<T> match) |
1
|
int FindLastIndex( int startIndex, int count, Predicate<T> match) |
搜索指定的对象,并返回第一个匹配项的从零开始的索引
1
|
int IndexOf(T item) |
搜索指定的对象,并返回从指定索引到最后一个元素的元素范围内第一个匹配项的从零开始的索引
1
|
int IndexOf(T item, int index) |
1
|
int IndexOf(T item, int index, int count) |
搜索指定的对象,并返回最后一个匹配项的从零开始的索引。
1
|
int LastIndexOf(T item) |
1
|
int LastIndexOf(T item, int index) |
1
|
int LastIndexOf(T item, int index, int count) |
4-5二分查找
使用默认的比较器在整个已排序的List中搜索元素,并返回该元素从零开始的索引。
1
|
int BinarySearch(T item); |
使用指定的比较器在整个已排序的List中搜索元素,并返回该元素从零开始的索引。
1
|
int BinarySearch(T item, IComparer<T> comparer) |
1
|
int BinarySearch( int index, int count, T item, IComparer<T> comparer) |
4-6排序
使用默认比较器对整个List中的元素进行排序。
1
|
void Sort() |
使用指定的 System.Comparison 对整个 List中的元素进行排序。
1
|
void Sort(Comparison<T> comparison) |
使用指定的比较器对List中的元素进行排序。
1
|
void Sort(IComparer<T> comparer) |
1
|
void Sort( int index, int count, IComparer<T> comparer) |
4-7性能分析
操作 | 时间复杂度 |
---|---|
Add | O(1)或O(n) |
Insert | O(n) |
Remove | O(n) |
GetAnItem | O(1) |
Sort | O(nlogn),最坏O(n^2) |
Find | O(n) |
4-8 附使用陷阱点:
1 list.Min() 和 list.Max() 和 Average()等Linq方法,当list元素个数为0,则会出现“序列不包含任何元素”的异常。
2 object.ToString() 使用前要检测object是否为null。
3 Foreach遍历时,迭代器是不允许增加或删除的。例如:
1
2
3
4
5
6
7
8
9
10
|
public List<MDevice> GetNormalDevices(List<MDevice> devices) { rtnDevices = devices; foreach ( var device in devices) { var tmpdevices = bslMDevice.GetMDeviceByDeviceCode(device.DeviceCode); if (!devices[0].IsNormal) { //这是非法的,因为移除rtnDevices列表的一个元素,等价于移除devices列表。 rtnDevices.Remove(device); } } } |
5 SortedList
5-1 SortedList简介
Sorted表明了它内部实现自动排序,List表明了它有点像List,可以通过index访问集合中的元素。
5-2 内部实现机理
一个SortedList对象内部维护了2个数组,以此来存储元素,其中一个数组用来存放键(keys),另一个存放键关联的值(values)。每一个元素都是键值对(key/value pair)。key不能是null,value可以。
5-3 总结API
5-3-1 Capacity
一个SortedList对象的容量是SortedList能容纳的元素数,这个值是动态变化,自动调整的。如下所示:
1
2
3
4
5
6
|
SortedList mySL = new SortedList(); mySL.Add( "Third" , "!" ); mySL.Add( "Second" , "World" ); mySL.Add( "First" , "Hello" ); Console.WriteLine( "mySL" ); Console.WriteLine( " Capacity: {0}" , mySL.Capacity ); |
此时Capacity: 16
如果添加到mySL中的元素增多,相应的Capacity会相应的自动变大。
5-3-2 访问元素
通过index访问
SortedList对象要想通过index访问,需要使用构造函数SortedList() 或 SortedList(IComparer icompared)。
1
2
3
4
|
SortedList sortedList = new SortedList(); sortedList.Add(3, "gz" ); sortedList.Add(9, "lhx" ); sortedList.Add(3, "gz" ); object getByIndex = sortedList.GetByIndex(2); |
通过key访问
SortedList对象要想通过key访问,需要使用带有TKey,TValue的泛型构造函数。
1
2
3
|
SortedList< int , string > sortedList = new SortedList< int , string >(); sortedList.Add(3, "gz" ); sortedList.Add(9, "lhx" ); object getByIndex = sortedList[3]; |
5-3-3排序
SortedList有一种默认的比较顺序,比如下面的代码:
1
2
3
|
SortedList< int , string > sortedList = new SortedList< int , string >(); sortedList.Add(9, "gz" ); sortedList.Add(3, "lhx" ); |
结果是 sortedList中第一个对是3,”lhx”
如果不想按照默认的排序顺序,需要自己在构造时定制一种排序顺序,如下面的代码:
实现排序接口
新建一个私有排序类,实现接口IComparer
1
2
3
4
5
|
private class ImplementICompare: IComparer< int > { public int Compare( int x, int y) { return x < y ? 1 : -1; } } |
构造SortedList
1
2
3
4
|
ImplementICompare impleCompare = new ImplementICompare(); SortedList< int , string > sortedList = new SortedList< int , string >(impleCompare); sortedList.Add(9, "gz" ); sortedList.Add(3, "lhx" ); |
按照键从大到小的顺序排序,结果是 sortedList中第一个对是9,”gz”
5-3-4 添加元素
用add接口实现添加某个元素到集合中,不允许重复添加相同键。
1
2
3
|
SortedList< int , string > sortedList = new SortedList< int , string >(); sortedList.Add(9, "gz" ); sortedList.Add(3, "lhx" ); |
5-3-5 移除元素
移除集合中指定元素Remove(object removedElement);指定index处移除元素RemoveAt(int index)。
Remove(object)
1
2
3
4
5
6
|
SortedList mySL = new SortedList(); mySL.Add( "3c" , "dog" ); mySL.Add( "2c" , "over" ); mySL.Add( "3a" , "the" ); mySL.Add( "3b" , "lazy" ); mySL.Remove( "3b" ); //sucessful to remove |
1
2
3
|
SortedList< int , string > sortedList = new SortedList< int , string >(); sortedList.Add(9, "gz" ); sortedList.Add(3, "lhx" ); bool removedFlag = sortedList.Remove(3); //true |
1
2
3
4
|
ImplementICompare impleCompare = new ImplementICompare(); SortedList< int , string > sortedList = new SortedList< int , string >(impleCompare); sortedList.Add(9, "gz" ); sortedList.Add(3, "lhx" ); bool removedFlag = sortedList.Remove(3); //false |
这是需要注意的一个地方,构造器带有impleCompare实现了排序接口时,好像不能移除某个元素,需要待确认。
RemoveAt(int index)
1
2
3
4
|
SortedList sorted = new SortedList(); sorted.Add(9, "gz" ); sorted.Add(3, "lhx" ); sortedList.RemoveAt(1); //在排序后的位置移除,sortedList的一个对的键 为3,第二个对的键为9,因此移除了9这个键值对 |
5-4 性能
一个SortedList的操作相比Hashtable对象是要慢些的,由于它实现了排序功能。但是,SortedList提供了访问的方便性,由于既可以通过index,也可以通过key去访问元素。
6 .net容器相关接口
接口 | 描述 |
---|---|
IEnumerable< T> | 实现foreach语句需要实现此接口,接口方法GetEnumerator返回枚举器。 |
ICollection< T> | 方法:Count属性,CopyTo(Array),Add, Remove, Clear |
IList< T> | 定义了indexer,Insert, RemoveAt方法,继承ICollection< T> |
ISet< T> | 方法:求并集,交集,继承于ICollection< T> |
IDictionary< TKey, TValue> | 有key和value的集合实现 |
ILookup< TKey, TValue> | 类似上,允许multiple values with one key. |
IComparer< T> | comparer实现,排序比较的规则 |
IEqualityComparer< T> | 对象be compared for equality另一个对象 |
IProducerConsumerCollection< T> | thread-safe collection classes |
7 接口UML
8 各个容器时间复杂度
集合类型 | Add | Insert | Remove | Item | Sort | Find |
---|---|---|---|---|---|---|
List< T> | O(1)或O(n) | O(n) | O(n) | O(1) | O(nlogn) | O(n) |
Stack< T> | O(1)或O(n) | 不适用 | pop() O(1) | 不适用 | 不适用 | 不适用 |
Queue< T> | O(1)或O(n) | 不适用 | O(1) | 不适用 | 不适用 | 不适用 |
HashSet< T> | O(1)或O(n) | O(1)或O(n) | O(1) | 不适用 | 不适用 | 不适用 |
LinkedList< T> | O(1) | O(1) | O(1) | O(n) | 不适用 | O(n) |
Dictionary<, > | O(1)或O(n) | 不适用 | O(1) | O(1) | 不适用 | 不适用 |
SortedDictionary<,> | O(logn) | 不适用 | O(logn) | O(logn) | 不适用 | 不适用 |
SortedList<,> | O(logn) | 不适用 | O(n) | O(logn) | 不适用 | 不适用 |
C#容器类,性能介绍的更多相关文章
- OpenHarmony 3.1 Beta版本关键特性解析——ArkUI容器类API介绍
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 刘鑫 容器类,顾名思义就是存储的类,用于存储各种数据类型的元素,并具备一系列处理数据元素的方法.在 ArkUI 开发框 ...
- 1 开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你。 本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的原则已经被许多现有的JDBC应用程序编译运行并验证过。 这些指导原则包括: 正确的使用数据库MetaData方法 只获取需要的数据 选用最佳性能的功能 管理连
1 开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你. 本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的 ...
- YII千万级PV架构经验分享--俯瞰篇--性能介绍
一张图,啥也不说了.直接上图,大图真难画. 呃,非得写满二百个字,其实本来想画均衡负债,一些服务器假设列子的,突然发现,没有业务要求,画不出来.写了这么久了,天天熬夜,得休息几天再继续.其实还有非常重 ...
- 4G工业路由器的性能介绍和应用需求
4G工业路由器可以实现数据的远程传输和设备控制功能,主要应用的场景包括智能电网.智能交通.智能家居.才智金融.工业自动化.公共安全.环境保护.数字化医疗等领域,特别是大数据或是视频传输等.那么4G工业 ...
- 标准C++中的STL容器类简单介绍
SGI -- Silicon Graphics[Computer System] Inc.硅图[计算机系统]公司. STL -- Standard Template Library 标准模板库. ...
- HarmonyOS方舟开发框架容器类API的介绍与使用
作者:liuxin,华为高级工程师 容器类,顾名思义就是存储的类,用于存储各种数据类型的元素,并具备一系列处理数据元素的方法.在方舟开发框架中,容器类采用了类似静态的语言来实现,并通过NAPI框架对外 ...
- 数据库性能监测工具——SQL Server Profiler
使用SQL Server Profiler 进行sql监控需要一些设置: 其他的就是进行分析了~ 清除SQL SERVER缓存 常用的方法: DBCC DROPCLEANBUFFERS 从缓冲池中删除 ...
- linux性能监控分析及通过nmon_analyse生成分析报表
nmon是一款分析 AIX 和 Linux 性能的免费工具 nmon 工具还可以将相同的数据捕获到一个文本文件,便于以后对报告进行分析和绘制图形.输出文件采用电子表格的格式 (.csv). 性能介绍 ...
- JavaScript性能优化 DOM编程
最近在研读<高性能JavaScript>,在此做些简单记录.示例代码可在此处查看到. 一.DOM 1)DOM和JavaScript 文档对象模型(DOM)是一个独立于语言的,用于操作XML ...
随机推荐
- FortiGate双链路不同运营商上网配置
1.防火墙端口配置 2.LLB配置
- Java18-java语法基础——集合框架
Java18-java语法基础——集合框架 一.什么是集合框架 1.集合框架:是为表示和操作集合而规定的一种统一的.标准的体系结构. 2.任何集合框架都包含三大块内容:对外的接口.接口的实现和对集合运 ...
- hdpi对应分辨率
ldpi QVGA (240×320) mdpi HVGA (320×480) hdpi WVGA (480×800),FWVGA (480×854) xhdpi 720P(1280*720) ...
- nginx路径设置(web)
原文 https://www.jianshu.com/p/57db2c5d0cb9 语法 root 语法:root path 默认值:root html 配置段:http.server.locatio ...
- dismiss 多个viewController
控制器堆栈是dismiss掉下面的,上面的自动就dismiss. [self.presentingViewController.presentingViewController dismissView ...
- linux学习第八天 (Linux就该这么学)
今天学了,mount 挂载,umount撤销挂载,.fdisk 命令 管理硬盘 交换分区swap,硬盘配额 xfs_quota命令 今天工作,手机看了,看的不全,回头看录播了.
- [JAVA]JAVA章3 如何获取及查看DUMP文件
一.dump基本概念 在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题.这些文件记录了JVM运行期间的内存占用.线程执行等情况,这就是我们常说的 ...
- Netsharp下载及环境搭建
作者:秋时 日期:2014-02-22 转载请保留原文链接 更新日志 2014-02-22 版本4.0 第一次发布 2014-04-19 版本4.01 修复网友提的部分bug,添加Netshar ...
- java多线程系列9 高级同步工具(3) CyclicBarrier
CyclicBarrier 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point) 然后一再执行 public class CyclicBar ...
- Chapter3_操作符_直接常量和指数计数法
(1)直接常量 在程序中使用直接常量,相当于指导编译器,告诉它要生成什么样的类型,这样就不会产生模棱两可的情况.比如flaot a = 1f等,后缀表示告诉编译器想生成的类型.常用的后缀有l/L(lo ...