C#学习总结之集合
一、集合接口和类型
命名空间:
集合类型 | 命名空间 |
一般集合 | System.Collections |
泛型集合 | System.Collections.Generic |
特定类型集合 | System.Collections.Specialized |
线程安全集合 | System.Collections.Concurrent |
不可变集合 | System.Collections.Immutable |
接口说明:
接口 | 说明 |
IEnumerable<T> | 如果将foreach语句用于集合,就需要IEnumerable接口。此接口定义了GetEnumerator()方法,返回一个实现了IEnumerator接口的枚举。 |
ICollection<T> | ICollection<T>接口由泛型集合类实现。使用这个接口可以获得集合中的元素个数(Count属性),把集合复制到数组中(CopyTo()方法),从集合添加和删除元素(Add(),Remove(),Clear())。 |
IList<T> |
IList<T>接口用于可通过位置访问其中的元素列表,此接口定义了一个索引器,可以在集合的指定位置插入或删除某些项(Insert()和RemoveAt()方法)。IList<T>接口派生自ICollection<T>接口。 |
ISet<T> |
ISet<T>接口由集实现。集允许合并不同的集,获得两个集的交集,检查两个集是否重叠。ISet<T>接口派生自ICollection<T>接口。 |
IDictionary<TKey,TValue> | IDictionary<TKey,TValue>接口由包含键和值的泛型集合类实现。使用此接口可以访问所有的键和值,使用键类型的索引器可以访问某些项,还可以添加或删除某些项。 |
ILookup<TKey,TValue> | 类似于IDictionary<TKey,TValue>接口,可以通过一个键包含多个值。 |
IComparer<T> | 由比较器实现,通过Compare()方法给集合中的元素排序。 |
IEqualityComparer<T> | 由比较器实现,用于字典中的键。使用此接口可对对象进行相等性比较。 |
IProductConsumerCollection<T> | .NET4.0后添加,支持新的线程安全的集合类。 |
IReadOnlyCollectiton<T> IReadOnlyList<T> IReadOnlyDictionary<TKey,TValue> |
用于初始化后不能修改的集合,这些接口的成员只允许检索对象,不能添加或修改它们。 |
IImmutableArray<T> IImmutableList<T> IImmutableQueue<T> IImmutableSet<T> IImmutableDictionary<TKey,TValue> |
不可变接口定义了用于不可变集合的方法和属性,这些集合在初始化后不能修改。 |
二、列表
调用默认构造函数创建列表对象:
var intList = new List<int>();
*使用默认构造函数创建空列表,元素添加到列表中后,列表容量会首先扩大到可容纳4个元素,每次超过容量后会重新设置为原来的2倍。列表容量改变,就要重新分配到一个新的内存块中,创建一个新的数组,使用Array.Copy()方法将旧的数组中的元素复制到新的数组中。
获取和设置集合的容量:
intList.Capacity = ;
获取集合元素的数量(Count属性):
Console.WriteLine(intList.Count);
释放不需要的容量:
intList.TrimExcess();
- 集合初始化设定项
,};
*集合初始值设定项没有反映在已编译的程序集的IL代码中,编译器会把集合初始值设定项变成对初始值设定项列表中的每一项调用Add()方法。
- 添加元素
intList.Add();
intList.AddRange(new int[]{1,2,3});
- 插入元素
intList.Insert(,); intList.InsertRange(,,,,});
- 访问元素
使用for循环遍历集合中的元素,通过索引器访问元素:
; i < intList.Count; i++) { Console.WriteLine(intList[i]); }
使用foreach语句遍历集合中的元素:
foreach (int i in intList) { Console.WriteLine(i); }
使用ForEach()方法:
intList.ForEach(Console.WriteLine);
- 删除元素
使用RemoveAt()方法删除元素:
intList.RemoveAt();
使用Remove()方法删除元素:
]; intList.Remove(i);
*按索引删除比较快,因为必须在集合中搜索要删除的元素。Remove()方法先检查元素类型是否实现了IEquatable<T>接口。如果是,就调用这个接口的Equals()方法,确定集合中的元素是否存在等于传递给Equals()方法的元素。如果没有实现这个接口,就使用Object类的Equals()方法比较这些元素。Object类中的Equals()方法的默认实现代码对值类型进行按位比较,对引用类型只比较其引用。
使用RemoveRange()方法删除元素(索引加位数):
intList.RemoveRange(,);
使用RemoveAll()方法删除指定特性的所有元素:
== );
使用Clear()方法删除集合中的所有元素:
intList.Clear();
- 搜索
使用Exists()方法检查元素是否存在:
intList.Exists(it => it == );
使用IndexOf()方法返回指定元素在集合中的索引,如果没有找到,则返回-1:
Console.WriteLine(intList.IndexOf());
使用FindIndex()、FindLastIndex()方法返回指定元素在集合中的索引:
);
int lastIndex = intList.FindLastIndex(r => r == 6);
使用Find()方法返回集合中指定的元素:
);
使用FindAll()方法获取与Predicate<T>类型匹配的所有项:
List<); foreach (int i in newIntList) { Console.WriteLine(i); }
- 排序
使用Sort()方法排序:
intList.Sort();
- 类型转换
使用ConvertAll<TOutput>()方法把集合转换为另一种类型:
List<string> stringList = intList.ConvertAll<string>(r => r.ToString() + "(I'm string)");
使用AsReadOnly()方法返回只读集合:
ReadOnlyCollection<int> readOnlyCollection = intList.AsReadOnly();
三、队列
队列是其元素以先进先出的原则来处理的集合,队列使用System.Collections.Generic命名空间下的泛型类Queue<T>实现。它实现了ICollection和IEnumberable<T>接口,但没有实现ICollection<T>接口,因此不能使用Add()和Remove()方法,且没有实现IList<T>接口,所以不能使用索引器访问队列。
Queue<T>类的方法说明
Queue<T>类的成员 | 说明 |
Count | Count属性返回队列中的元素个数 |
Enqueue | Enqueue()方法在队列一端添加一个元素 |
Dequeue | Dequeue()方法在队列的头部读取和删除一个元素。如果调用时队列中没有元素,则抛出一个InvalidOperationException类型的异常 |
Peek | Peek()方法从队列的头部读取一个元素,但不删除它 |
TrimExcess | TrimExcess()方法重新设置队列的容量。Dequeue()方法从队列中删除元素,但它不会重新设置队列的容量。要从队列的头部去除空元素,应使用TrimExcess()方法 |
public class Document { public string Title { get; private set; } public string Content { get; private set; }
public Document(string title, string content) { this.Title = title; this.Content = content; } } public class DocumentManager { private readonly Queue<Document> documentQueue = new Queue<Document>(); public void AddDocument(Document doc) { lock (this) { documentQueue.Enqueue(doc); } } public Document GetDocument() { Document doc = null; lock (this) { doc = documentQueue.Dequeue(); } return doc; } public bool IsDocumentAvailable { get { ; } } }
四、栈
栈是一个后进先出的容器,使用Push()方法在栈中添加元素,用Pop()方法获取最近添加的元素。
Stack<T>类的方法说明
Stack<T>类的成员 | 说明 |
Count | 返回栈中的元素个数 |
Push | 在栈顶添加一个元素 |
Pop | 从栈顶删除一个元素,并返回该元素,如果栈是空的,就抛出InvalidOperationException异常 |
Peek | 返回栈顶的元素,但不会删除它 |
Contains | 确定某个元素是否在栈中,如果是,就返回true |
var alphabet = new Stack<char>(); alphabet.Push('A'); alphabet.Push('B'); alphabet.Push('C'); foreach (char item in alphabet) { Console.WriteLine(item); } Console.ReadLine(); //返回内容为C、B、A
五、链表
LinedList<T>是一个双向链表,其元素指向它前面和后面的元素。
链表的优点:在插入一个元素时,只需要修改上一个元素的Next引用和下一个元素的Previous引用即可。
链表的缺点:链表的元素只能一个接一个地访问,这需要较长的时间来查找位于链表中间或尾部的元素。
LinkedListNode<T>类型属性说明
属性 | 说明 |
List | 返回与节点相关的LinkedList<T>对象 |
Next | 用于遍历列表,返回当前节点之后的节点 |
Previous | 用于遍历列表,返回当前节点之前的节点 |
Value | 返回与节点相关的元素 |
六、有序列表
如果需要基于键对所需集合排序,可以使用SortedList<TKey,TValue>类。
var books = new SortedList<string, string>(); books.Add("Professional WPF Programming", "978-0-470-04180-2"); books.Add("Professional ASP.NET MVC 3", "978-1-1180-7658-3"); books["Beginning Visual C# 2010"] = "978-0-470-50226-6"; books["Professional C# 4 and .NET 4"] = "978-0-470-50225-9"; foreach (var book in books) { Console.WriteLine("{0} , {1}", book.Key, book.Value); } Console.ReadLine();
*如果使用索引器访问一个元素,若所传键值不存在,就会抛出一个KeyNotFoundException类型的异常。为了避免异常发生,可以使用ContainsKey()方法判断列表中是否有指定键值。也可以调用TryGetValue()方法尝试获得指定键的值。
string isbn; string title = "Professional C# 7.0"; if (!books.TryGetValue(title,out isbn)) { Console.WriteLine("{0} not found", title); }
七、字典
字典是一种可以按照某个键来访问元素的集合,用作字典中键的类型必须重写object类的GetHashCode()方法。字典的容量是一个素数,如果指定的容量不是素数的值,Dictionary<TKey,TValue>类会使用传递给构造函数的整数后面紧接着的一个素数来指定容量。
- Dictionary<TKey,TValue>类
使用Add()方法添加元素:
var myDictionary = new Dictionary<string, string>(); myDictionary.Add(", "Jack");
使用索引器添加元素:
myDictionary["] = "Mike";
使用TryGetValue()方法检查键值是否存在,若存在则返回true,否则返回false:
string person; myDictionary.TryGetValue(", out person);
- Lookup<TKey,TValue>类:
类似Dictionary<TKey,Tvalue>类,但把键映射在一个值集上。Lookup<TKey,Tvalue>类不能像一般字典那样创建,必须调用ToLookup()方法。
class Program { static void Main(string[] args) { var racers = new List<Racer>(); racers.Add(,)); racers.Add(,)); racers.Add(,)); racers.Add(,)); racers.Add(,)); var lookupRacers = racers.ToLookup(r => r.Country); foreach (Racer r in lookupRacers["Australia"]) { Console.WriteLine(r); } Console.ReadLine(); } } public class Racer { public int Id { get; private set; } public string FirstName { get; set; } public string LastName { get; set; } public string Country { get; set; } public int Wins { get; set; } public Racer(int id, string firstName, string lastName, string country, int wins) { this.Id = id; this.FirstName = firstName; this.LastName = lastName; this.Country = country; this.Wins = wins; } ) { } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } }
- SortedDictionary<TKey,TValue>类
SortedDictionary<TKey,TValue>类是一个二叉搜索树,其中的元素根据键来排序。该键的类型必须要实现Icomparable<TKey>接口。
八、集
包含不重复元素的集合称为"集(set)",.NET Framework包含两个集(HashSet<T>和SortedSet<T>)。HashSet<T>集包含不重复元素的无序列表,SortedSet<T>集包含不重复元素的有序列表。
方法 | 说明 |
Add | 返回一个布尔值,说明是否添加了元素 |
IsSubSetOf | 是否为子集 |
IsSupersetOf | 是否为超集 |
Overlaps | 确定是否当前的 Hashset对象和指定的集合共享通用元素 |
UnionWith | 并集 |
ExceptWith | 删除指定集合中的元素 |
var companyTeams = new HashSet<string>() { "Ferrari", "McLaren", "Mercedes" }; var traditionalTeams = new HashSet<string>() { "Ferrari", "McLaren" }; var privateTeams = new HashSet<string>() { "Red Bull", "Toro Rosso", "Force India", "Sauber" }; if (privateTeams.Add("Williams")) { Console.WriteLine("Williams Added"); } if (!companyTeams.Add("McLaren")) { Console.WriteLine("McLaren was already in this set"); } if (traditionalTeams.IsSubsetOf(companyTeams)) { Console.WriteLine("TraditionalTeams is subset of companyTeams"); } if (companyTeams.IsSupersetOf(traditionalTeams)) { Console.WriteLine("CompanyTeams is a superset of traditionalTeams"); } traditionalTeams.Add("Williams"); if (privateTeams.Overlaps(traditionalTeams)) { Console.WriteLine("At least one team is the same with the traditional and private teams"); } var allTeams = new SortedSet<string>(companyTeams); allTeams.UnionWith(privateTeams); allTeams.UnionWith(traditionalTeams); Console.WriteLine(); Console.WriteLine("All teams"); foreach (var team in allTeams) { Console.WriteLine(team); } allTeams.ExceptWith(privateTeams); Console.WriteLine(); Console.WriteLine("no private team left"); foreach (var team in allTeams) { Console.WriteLine(team); } Console.ReadLine();
九、可观察的集合
如果需要集合中的元素何时删除或添加的信息,就可以使用ObservableCollection<T>类,这个类的命名空间是System.Collections.ObjectModel。用户可以使用INotifyCollectionChanged接口注册CollectionChanged事件。
NotifyCollectionChangedEventArgs属性说明
属性 | 说明 |
Action | 是否添加或删除一项的信息 |
OldItems | 列出删除的项 |
NewItems | 列出新增的项 |
class Program { static void Main(string[] args) { var data = new ObservableCollection<string>(); data.CollectionChanged += Data_CollectionChanged; data.Add("One"); data.Add("Two"); data.Insert(, "Three"); data.Remove("One"); Console.ReadLine(); } static void Data_CollectionChanged(object sender, 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("old item(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("new item(s): "); foreach (var item in e.NewItems) { Console.WriteLine(item); } } Console.WriteLine(); } }
十、位数组
如果需要处理的数字有许多位,可以使用BitArray类和BitVector32结构。BitArray类位于命名空间System.Collectioins中,BitVector32结构位于命名空间System.Collections.Specialized中。区别:BitArray可以重新设置大小,BitVector32结构仅包含32位。
BitArray类:
BitArray类的成员 | 说明 |
Count Length | Count和Length属性的get访问器返回数组中的位数。使用Length属性还可以定义新的数组大小,重新设置集合的大小。 |
Item Get Set |
可以使用索引器读写数组中的位。索引器是布尔类型,除了使用索引器之外,还可以使用Get()和Set()方法访问数组中的位。 |
SetAll |
根据传送给该方法的参数,SetAll()方法设置所有位的值。 |
Not | Not()方法对数组中所有位的值取反 |
And Or Xor |
使用And()、Or()、Xor()方法,可以合并两个BitArray对象。And()方法执行二元AND,Or()方法执行二元OR,Xor()方法是异或操作。 |
BitVector32结构:
BitVector32结构的成员 | 说明 |
Data | Data属性把BitVector32结构中的数据返回给整数 |
Item | BitVector32的值可以使用索引器设置。索引器是重载的——可以使用掩码或BitVector32.Section类型的片段来获取和设置值。 |
CreateMask | 这是一个静态方法,用于为访问BitVector32结构中的特定位创建掩码。 |
CreateSection | 这是一个静态方法,用于创建32位中的几个片段。 |
C#学习总结之集合的更多相关文章
- 软件测试之loadrunner学习笔记-02集合点
loadrunner学习笔记-02集合点 集合点函数可以帮助我们生成有效可控的并发操作.虽然在Controller中多用户负载的Vuser是一起开始运行脚本的,但是由于计算机的串行处理机制,脚本的运行 ...
- python学习笔记整理——集合 set
python学习整理笔记--集合 set 集合的用途:成员测试和消除重复的条目,进行集合运算 注意:花括号或set()函数可以用于创建集合. 注意:若要创建一个空的集合你必须使用set(),不能用{} ...
- [推荐]PMO学习贴大集合
[推荐]PMO学习贴大集合 http://wenku.baidu.com/view/a9b19bd4240c844769eaeed9.html http://wenku.baidu.com/view/ ...
- [置顶] Guava学习之Immutable集合
Immutable中文意思就是不可变.那为什么需要构建一个不可变的对象?原因有以下几点: 在并发程序中,使用Immutable既保证线程安全性,也大大增强了并发时的效率(跟并发锁方式相比).尤其当一个 ...
- Java学习笔记之---集合
Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...
- python学习-day14:集合,函数,格式化
一.集合 定义:由不同元素组成的集合.集合是一组无序排列的可hash值, 可以作为字典的key.元素必须是不可变类型:只能存放数字,字符串,字典 特性:集合的目的是将不同的值放在一起,不同的集合之间可 ...
- 不学就吃亏的underscorejs类库学习示例 ——(集合篇)
underscorejs是一个很不错的类库,我的很多项目都引用了这个类库,的确可以带来很多方便. 记得我当初学的时候,看underscorejs的api是看的一知半解的,甚至不明白api里的conte ...
- 有关JAVA基础学习中的集合讨论
很高兴能在这里认识大家,我也是刚刚接触后端开发的学习者,相信很多朋友在学习中都会遇到很多头疼的问题,希望我们都能够把问题分享出来,把自己的学习思路整理出来,我们一起探讨一起成长. 今天我 ...
- Java学习笔记之集合
集合(Collection)(掌握) (1)集合的由来? 我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组而数组的长度固定 ...
- 【原】Java学习笔记026 - 集合
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:从三国演义中 ...
随机推荐
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
- 传播正能量——做一个快乐的程序员
引子 今天在博客园看到施瓦小辛格的文章我们搞开发的为什么会感觉到累,顿时有感而发.自己本来不擅长写文章,更不擅长写这种非技术性的文章,但是在思绪喷薄之际,还是止不住有很多话要说.针对从客观上说&quo ...
- AutoMapper随笔记
平台之大势何人能挡? 带着你的Net飞奔吧! http://www.cnblogs.com/dunitian/p/4822808.html#skill 先看效果:(完整Demo:https://git ...
- 让 windows 下的命令行程序 cmd.exe 用起来更顺手
在 Windows 下使用 Larave 框架做开发,从 Composer 到 artisan 总是避免不了和 cmd.exe 打交道,系统默认的命令行界面却是不怎么好看,且每行显示的字符数是做了限制 ...
- Android Button的基本使用
title: Android Button的基本使用 tags: Button,按钮 --- Button介绍: Button(按钮)继承自TextView,在Android开发中,Button是常用 ...
- 如何在ASP.Net创建各种3D图表
我们都知道,图表在ASP.NET技术中是一种特别受欢迎而又很重要的工具.图表是表示数据的图形,一般含有X和Y两个坐标轴.我们可以用折线,柱状,块状来表示数据.通过图表控件,我们即能表示数据又能比较各种 ...
- WebGIS中等值面展示的相关方案简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...
- ZKWeb网页框架1.3正式发布
本次更新的内容有 更新引用包版本 Microsoft.AspNetCore.Hosting.Abstractions 1.1.0 Microsoft.AspNetCore.Http.Abstracti ...
- 【夯实PHP基础】nginx php-fpm 输出php错误日志
本文地址 原文地址 分享提纲: 1.概述 2.解决办法(解决nginx下php-fpm不记录php错误日志) 1. 概述 nginx是一个web服务器,因此nginx的access日志只有对访问页面的 ...