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) { // 需求:从三国演义中 ...
随机推荐
- .NET基础拾遗(5)多线程开发基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- JavaScript动画-碰撞检测
▓▓▓▓▓▓ 大致介绍 碰撞检测是指在页面中有多个元素时,拖拽一个元素会出现碰撞问题,碰撞检测是以模拟拖拽和磁性吸附中的范围限定为基础的 效果:碰撞检测 ▓▓▓▓▓▓ 碰撞检测 先来看看碰撞检测的原理 ...
- [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性
回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...
- JQuery easyUI DataGrid 创建复杂列表头(译)
» Create column groups in DataGrid The easyui DataGrid has ability to group columns, as the followin ...
- SQL Server 2016白皮书
随着SQL Server 2016正式版发布日临近,相关主要特性通过以下预览学习: Introducing Microsoft SQL Server 2016 e-bookSQL Server 201 ...
- PHP中PDO事务的使用方法
事务 (Transaction) 是操作数据库中很重要的一个功能, 它可以让你预定一条, 或者一系列 SQL 语句, 然后一起执行. 在执行的过程中, 如果其中的某条执行失败, 可以回滚所有已更改的操 ...
- JQuery中的siblings()是什么意思
jQuery siblings() 方法返回被选元素的所有同胞元素,并且可以使用可选参数来过滤对同胞元素的搜索. 实例演示:点击某个li标签后将其设置为红色,而其所有同胞元素去除红色样式. 1.创建H ...
- 【SAP业务模式】之ICS(五):定价配置
本篇博文讲述ICS业务中的定价配置. 1.定义销售订单类型 目录:SPRO-销售与分销-销售-销售凭证-销售凭证抬头-定义销售凭证类型 事务代码:VOV8 2.定义销售订单类型 目录:SPRO-销售与 ...