C#之再议数组和集合
1.数组
1.1简单数组
1.2 多维数组
1.3锯齿数组
1.4Array数组
1.5作为参数的数组
1.6枚举
1.7结构
以上部分可参考 http://www.cnblogs.com/ztb123/articles/4195864.html
1.8元组
数组合并了相同类型的对象,而元组合并了不同类型的对象.Net 4定义了 8个泛型 Tuple类 和一个静态 Tuple类 ,它们用作元组的工厂。 这里的不同泛型 Tuple类支持不同数量的元素。 例如,Tuple<T1> 包含-个元素,Ttple<T1,T2> 包含两个元素,以此类推,元组用Tuple的静态Create()方法创建。
public static Tuple<int, int> Divide(int dividend, int divisor) { int result = dividend / divisor; int reminder = dividend % divisor; return Tuple.Create(result, reminder); } ,); Console.WriteLine("result if division:{0},reminder:{1}", result.Item1, result.Item2);
Demo
如果元组包含的项超过 8个,就可 以使用 带 8个参数的 Tuple类 定义。 最后一个模板参数是 TRrest,表示必须给它传递一个元组。 这样,就可以创建带任意个参数的元组了,可在类上右键转到定义查看。
2集合
2.1集合和接口类型
大多数集合类都可在 systm.Collections和 system.Collections.Generic名称空间中找到 。 泛型集合 类 位 于System.Collections.Generic名 称 空 间 中,专门于特定类型的集合类位于System.Collections.Specialized名称空间中,线程安全的集合位于System.Collections.Concurrent名称空间中。
集合和列表实现的接口:
- IEnumerable<T> 如果将Foreache语句用于集合,就需要IEnumerable接口,这个接口定义了GetEnumerator()方法,它返回一个实现了IEnumable接口的枚举。
- ICollection<T> 这个接口由泛型集合类实现。使用这个接口可以获得集合中的元素个数(Count属性),把集合复制到数组中(CopyTo()方法),还可以从集合中添加和删除元素(Add(),Remove(),Clear())
- IList<T> 此接口用于 可通过位置访问其中的元素的列表,这个接口定义了一个索引器,可以在集合的指定位置插入或删除某些项,此接口派生自ICollection<T>接口
- ISet<T> 实现这个接口的集合可以允许合并不同的集,获得2个集合的交集,检查2个集合是否重叠,此接口派生自ICollection<T>接口
- IDictionary<TKey,TValue> 此接口有包含键和值的泛型集合实现,使用这个接口可以访问所有的键和值,使用键类型的索引可以访问某些项,还可以添加和删除某些项。
- ILookup<TKey,TValue> 此接口类似于IDictionary<TKey,TValue>接口,实现此接口的集合有键和值,且可以通过一个键包含多个值。
- IComparer<T> 此接口由比较器实现,通过compare()方法给集合中的元素排序
- IEquaityComparer<T>此接口由一个比较器实现,发、该比较器可以用于字典中的键。使用这个接口可以对对象进行相等性比较。
- IProducerConsumerCollection<T>此接口支持新的线程安全的集合类
2.2列表
.Net Framework为动态列表提供了泛型类List<T>.这个类实现了IList,IConllection,IEnumerable IList<T>,ICollection<T>和IEnunerable<T>接口。
使用默认的构造函数创建一个空列表,元素添加到列表后,列表的容量就会扩大为可接纳4个元素,如果添加了第5个元素,列表的大小就会变为原来的2倍,以此类推。如果列表的容量改变了,整个集合就会重新分配到一个新的内存中,所以为了节省时间,如果事先知道列表的容量,就可以用构造函数定义其容量。
List<, }; list.Add();//添加 list.Insert(, );//插入 ; i < list.Count; i++) { Console.WriteLine(list[i]);//访问元素 } list.RemoveAt();//删除 );//查找 list.Sort();//排序 foreach (var item in list) { Console.WriteLine(item); } list.AsReadOnly();//设置为只读集合,所有的修改集合的方法和属性都会抛出NotSupportedExection异常
List
2.3队列
队列是其元素 以先进先出的 方式来处理的集合。使用泛型类Queue<T>实现
Queue<T>类的方法:
- Count 返回队列中的元素个数
- Enqueue()在队列的一段添加一个元素
- Dequeue()在队列的头部读取和删除一个元素。如果队列中没有元素会抛出一个InvalidOperationException类型的异常。
- Peek() 从队列的头部读取一个元素,但不会删除它
- TrimExcess() 重新设置队列的容量,Dequeue()方法从队列中删除元素,但不会重新设置队列的容量,要从队列的头部去除空元素,应使用此方法。
2.4栈
栈是与队列非常相似的一个容器,但它是先进后出。
Statck<T>类的成员:
- Count 返回栈中的元素个数
- Push() 在栈顶部添加一个元素
- Pop()从栈顶部移除一个元素,并返回该元素。如果栈是空的,就会抛出一个InvalidOPerationExcepron异常
- Peek() 返回栈顶部的元素,但不删除
- Contains() 确定某个元素是否在栈中,如果是返回true
2.5链表
LinkList<T>是一个双向链表,其元素指向它前面和后面的元素。链表的优点是,如果将元素插入到列表的中间位置,使用链表会非常快,在插入一个元素时,只需修改上一个元素的 Next引 用和下一个元素的Previous引用 ,使 它们引用所插入的元素。缺点是链表元素只能一个接一个的访问。
2.6有序列表
如果需要基于键对所需集合排序,就可 以使用 SoftedList<TKey,TValue>类。这个类按照键给元素排序。 集合中的键和值都可以使用任意类型。
var books = new SortedList<string, string>(); books.Add("C# 2012 wrox box","978-987-9989-7"); books.Add("Professional", "978-987-9989-9"); books["Beginning Visual C# 2008"] = "978-987-9989-8"; books["C# 2008"] = "978-987-9989-5"; foreach (KeyValuePair<string,string> book in books) { Console.WriteLine("{0},{1}",book.Key,book.Value); }
SoftList
输出默认按键的顺序输出。
2.7字典
字典表示一种非常复杂的数据结构,这种数据结构允许按照某个键来访问元素字典也称为映射或散列表。字典的主要特性是能根据键快速查找值 。也可以自由添加和删除元素,但 没有在 内存中移动后续元素的性能开销。
Dictionary<int, int> dic = new Dictionary<int, int>(); dic.Add(, ); dic[] = ; dic[] = ; dic.Add(,); dic.Remove(); foreach (var item in dic) { Console.WriteLine("key:{0},Value:{1}",item.Key,item.Value); }
Dictionary
2.7.1 有序字典
SortedDictionary<TKey,TValue>类是一个二叉搜索树,其中的元素根据键来排序。
- SortedList<TKey,TValue>类使用的内存比SortedDictionay<TKey,TValue>类少
- SortedDictionay<TKey,TValue>类的元素的插入和删除速度比较快
- 在用 已排好序的数据填充集合时,若 不需要修改容量,SortedList<TKey,TValue> 比较决
2.8 集合
包含不重复元素的集合称为"集" 。 .NET4包 含两个集(HashSet<T>(无序)和SortedList<T>(有序))。
, , , , }; , , , , }; set1.ExceptWith(set2); foreach (var item in set1) { Console.WriteLine(item); } set1.UnionWith(set2); foreach (var item in set1) { Console.WriteLine(item); }
HashSet
2.9可观察的集合
如果需要集合中的元素何时删除或添加的信息,就可以使用ObservableCollection<T>类,这个类是为WPF定义的,这样UI就可以知道集合的变化。这个类需要映入程序集WindowBase,
var date =new ObservableCollection<string>(); date.CollectionChanged += Date_CollectionChanged; date.Add("); date.Insert(, "); date.Remove("); Console.ReadKey(); private static void Date_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { Console.WriteLine("action{0}",e.Action.ToString()); if (e.OldItems != null) { Console.WriteLine("starting index for old item(s):{0}",e.OldStartingIndex); Console.WriteLine("OldItem(s):"); foreach (var item in e.OldItems) { Console.WriteLine(item); } } if (e.NewItems != null) { Console.WriteLine("starting index for new item(s):{0}", e.NewStartingIndex); Console.WriteLine("NewItem(s):"); foreach (var item in e.NewItems) { Console.WriteLine(item); } } Console.WriteLine(); }
ObservableCollection
2.10并发集合
为了对集合进行线程安全的访问,定义了IProducerConsumerCollection<T>接口,这个接口重要的方法是TryAdd() (尝试给集合添加一项,如果集合禁止添加,这个操作就可能失败,返回一个Bool值)和TryTake()(工作方式和TryAdd相同,以通知调用者操作是成功还是失败,并在操作成功后返回集合中的项).
- ConcurrentQueue<T> 这个集合类用 一种免锁定的算法实现,使用在 内部合并到一个链表中的 32项数组.访 问队列元素的方法有 Enqueue()、 TryDequeue()和 TryPeek()。 这些方法的命名非常类似Queue<T>累的方法,只是个可能调用失败的方法前边加了Try.因为这个类实现了IProducerConsumerCollection<T>接口,所以TryAdd()和TryTake()方法值调用Enqueue()和TryDequeue()方法。
- ConurrentStack<T> 类似于ConcurrentQueue<T> 只 是带有另外的元素访 问方法。此类定义了Push().PushRange().TryPeek().TryPop()和TryPopRange()方法。
- ConcurrentDictionary<TKey,TValue> 这是一个线程安全的键值集合。TryAdd().TryGetValue().TryRemove()和TryUpdate()方法以非阻塞的方式访问成员,因为元素基于键和值,所以此类没有实现IProducerConsumerCollection<T>接口。
- BlockingCollection<T> 这个集合在可以添加和删除之前会阻塞线程并一直等待。它提供了一个接口,以使用Add()和Take()方法来添加和删除元素。
var sharedCollection = new BlockingCollection<int>(); ]; ]; ; i < ; i++) { events[i] = new ManualResetEventSlim(false); waits[i] = events[i].WaitHandle; } var producer = new Thread(obj=> { var state = (Tuple<BlockingCollection<int>,ManualResetEventSlim>)obj; var coll = state.Item1; var ev = state.Item2; var r = new Random(); ; i < ; i++) { coll.Add(r.Next()); ev.Set(); } }); producer.Start(Tuple.Create<BlockingCollection<])); var consumer = new Thread(obj=> { var state = (Tuple<BlockingCollection<int>, ManualResetEventSlim>)obj; var coll = state.Item1; var ev = state.Item2; ; i < ; i++) { int result = coll.Take(); } ev.Set(); }); consumer.Start(Tuple.Create<BlockingCollection<])); if (!WaitHandle.WaitAll(waits)) Console.WriteLine("wait failed"); else Console.WriteLine("reading/writing finished"); Console.ReadKey();
BlockingCollection
C#之再议数组和集合的更多相关文章
- .NET 基础 一步步 一幕幕[数组、集合、异常捕获]
数组.集合.异常捕获 数组: 一次性存储多个相同类型的变量. 一维数组: 语法: 数组类型[] 数组名=new 数组类型[数组长度]; 声明数组的语法: A.数据类型 [] 数组名称= new 数据类 ...
- paip.数组以及集合的操作uapi java php python总结..
paip.数组以及集合的操作uapi 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...
- c#重点[集合类型]异常,数组,集合ArrayList,List<>,hashTable,hashtable泛型(Dictionary)
1.foreach[对一些数组或集合进行遍历] foreach(类型 变量名 in 集合对象){语句体} //定义一个数组 ,,,,, }; foreach(var i in sNum1) { Con ...
- Java比较器对数组,集合排序一
数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...
- 初学者入门web前端 C#基础知识:数组与集合
对于初学者,想要入门web前端,要有足够的信念和坚持,不然只会越走越远,我现在就深深的体会到. 我本是一个很拒绝代码的人,以前想过UI设计,但是在这段学习时间里,发现其实只要认真,代码并不是很难 所以 ...
- 第四十三条:返回零长度的数组或者集合,而不是null
如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长度的,也就是没有实际对象在里面, 我们也应该放回一个零长度的数组或者集合,而不是返回null.如果返回了null,客 ...
- 再议Java中的static关键字
再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...
- JAVA数组和集合谁是儿子
Java有哪些数据存储方式? 基本数据类型(1byte3整2小数1字符1布尔)分别是byte,short,int long,flort,double,char,boolean(颜色好喜庆的样子O(∩_ ...
- java中数组、集合、字符串之间的转换,以及用加强for循环遍历
java中数组.集合.字符串之间的转换,以及用加强for循环遍历: @Test public void testDemo5() { ArrayList<String> list = new ...
随机推荐
- 博弈论之Nim
博弈论(一):Nim游戏 重点结论:对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示位异或(xor)运算. Nim游戏是博 ...
- 【Demo 0009】Java基础-异常
本章学习要点: 1. 了解异常的基本概念: 2. 掌握异常捕获方法以及注意事项; 3. 掌握异常抛出方法: 4. 掌握自定义异常类和异常类继承注 ...
- Swift - 触摸事件(点击,移动,抬起等)说明及用例
在iOS开发中,UIGestureRecognizer可以方便的响应处理手势事件. 而如果要想更精细的处理,我们还需要借助touchesBegan,touchesMoved,touchesEnded等 ...
- android面试题2
一.属于GLSurFaceView特性的是: 1.管理一个surface,这个surface就是一块特俗的内存.能直接排版到Android的视图view上. 2.管理一个EGL display,它能让 ...
- 数据和C
整数就是没有小数部分的数,在C中小数点永远不会出现在整数中.例如2,-24,2456都是整数,整数以二进制存储,例如7的二进制表示为111,在8位的字节中存储它的前5位为0,将后3位置1. 浮点数即加 ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(三)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关 ...
- 14.2.2 InnoDB Multi-Versioning InnoDB 多版本
14.2.2 InnoDB Multi-Versioning InnoDB 多版本: InnoDB 是一个多版本的存储引擎: 它保留信息关于改变数据的老版本,为了支持事务功能 比如并发和回滚. 这些信 ...
- Shell 传递参数
Shell 传递参数 向脚本传递参数,格式为:$n. 向脚本传递三个参数,并分别输出: echo "Shell 传递参数实例!"; echo "第一个参数为:$1&quo ...
- Hbase集群环境搭建
Hbase数据库依赖 Hadoop和zookeeper,所以,安装Hbase之前,需要先把zookeeper集群搭建好.(当然,Hbase有内建的zookeeper,不过不建议使用).Hbase配置上 ...
- 部署到Linux使用VS Code 开发.NET Core 应用程序
使用VS Code 开发.NET Core 应用程序 部署到Linux 跨平台 使用VS Code 开发.NET Core 应用程序 部署到Linux 跨平台. 前面讲解了VSCode开发调试 .NE ...