C#集合(Collection)
C# 中的集合类(Collection)是专门用于数据存储和检索的类,类中提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash table)的支持。大多数集合类都实现了相同的接口。
集合类的用途多种多样,例如可以动态的为元素分配内存、根据索引访问列表项等等,这些类创建 Object 类的对象集合,Object 类是 C# 中所有数据类型的基类。
C# 中的集合类型
在 System.Collections.Generic,System.Collections.Concurrent 和 System.Collections 命名空间下提供了许多集合类型,每种集合类型都有特定的用途,下面以 System.Collection 命名空间为例,该命名空间下提供的集合类型如下表所示:
类 | 描述和用法 |
---|---|
动态数组(ArrayList) | 不固定长度和存储的数据类型的数组,可以存储任意类型的数据,并且长度会随着数据内容的增加减少进行改变 |
泛型集合(List) | 类似ArrayList,只是List只能存储相同类型的数据,List的长度也不是固定的 |
字典(Dictionary) | 类似List.只能存储固定类型的数据,长度不固定 |
哈希表(Hashtable) | 哈希表可以使用键来访问集合中的元素。 哈希表中的每一项都由一个键/值对组成,键用于访问集合中的指定项。 |
排序列表(SortedList) | 排序列表是数组和哈希表的组合,可以使用键或索引来访问列表中的各项。 排序列表中包含一个可使用键或索引访问各项的列表,如果您使用索引访问各项,则它是一个动态数组,如果您使用键访问各项,则它就是一个哈希表。 另外,排序列表中的各项总是按键值进行排序的。 |
堆栈(Stack) | 堆栈代表了一个后进先出的对象集合。 当您需要对各项进行后进先出的访问时,则可以使用堆栈。为堆栈中添加一项称为推入项目,从堆栈中移除一项称为弹出项目。 |
队列(Queue) | 队列代表了一个先进先出的对象集合。 当您需要对各项进行先进先出的访问时,则可以使用队列。为队列中添加项目称为入队,为队列中移除项目称为出队。 |
点阵列(BitArray) | 点阵列代表了一个使用 1 和 0 来表示的二进制数组。 当您需要存储比特位,但是事先不知道具体位数时,则可以使用点阵列。可以使用整型索引从点阵列集合中访问各项,索引从零开始。 |
C# ArrayList:动态数组
var
C# List:泛型集合
C# Dictionary 字典
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _01_Dictionary { internal class Program { static void Main(string[] args) { //字典:类似List,只能存储固定类型的数据,长度不固定 //Array ArrayList List使用索引进行数据的操作, 字典使用"键"进行数据的操作 //键: 标识 在一个字典中,键是唯一的 并且不能为null //格式:Dictionary<键的数据类型,值的数据类型> 变量名 =new Dictionary<键的数据类型,值的数据类型>(); Dictionary<string,int> keyValuePairs = new Dictionary <string,int>() { {"Name",555 }, {"777",6666 }, {"K",8888 }, {"吴亦凡",9999 }, //键是在运行期间校验的 {"吴亦凡1",999 } }; //向字典中添加数据 keyValuePairs.Add("罗志祥",999); //通过键获取值 //取值 Console.WriteLine(keyValuePairs["Name"]); Console.WriteLine(keyValuePairs["K"]); //通过键修改值 keyValuePairs["K"] = 6666; Console.WriteLine(keyValuePairs["K"]); //表示字典中存储的数据的个数 Console.WriteLine(keyValuePairs.Count); //判断字典中是否拥有指定的Key(键) Console.WriteLine(keyValuePairs.ContainsKey("吴亦凡22")); //判断字典中是否拥有指定的value(值) Console.WriteLine(keyValuePairs.ContainsValue(98989)); //字典的作用:一般用于一些信息的记录,用字典存储的数据,可以加快查询的速度 } } }
C# Hashtable:哈希表
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _02_Hashtable { internal class Program { static void Main(string[] args) { //Hashtable Hash表 表示一系列由键和值组成的数据,使用键进行访问 //hash表中添加键值对,键必须是唯一的,数据类型不限制 Hashtable hashtable = new Hashtable() { {0,"1" }, {"a",3 }, }; hashtable.Add(1, "吴亦凡"); hashtable.Add(2, "罗志祥"); hashtable.Add("吴亦凡", 3); //Keys 获取hash表中所有的键 Console.WriteLine(hashtable.Keys); //Values 获取hash表中所有的值 Console.WriteLine(hashtable.Values); Console.WriteLine(hashtable.Count); //注意:因为hash表中,所有的数据类型都是不固定的,因此在遍历key或者value 的时候,只能标注为var/object类型 foreach (var k in hashtable.Keys) { Console.WriteLine(k); } Console.WriteLine(hashtable[0]); hashtable[0] = "吴亦凡"; //删除指定的键对应的数据 hashtable.Remove("吴亦凡"); //清空hash表 hashtable.Clear(); Console.WriteLine(hashtable.ContainsKey("1.1")); Console.WriteLine(hashtable.ContainsValue("吴亦凡")); } } }
Hashtable 类中的属性
下表中列出了 Hashtable 类中一些常用的属性:
属性 | 描述 |
---|---|
Count | 获取哈希表中包含的键值对的个数 |
IsFixedSize | 获取一个值,用来表示哈希表是否具有固定大小 |
IsReadOnly | 获取一个值,用来表示哈希表是否只读 |
Item | 获取或设置与指定键关联的值 |
Keys | 获取一个 ICollection,其中包含哈希表中的键 |
Values | 获取一个 ICollection,其中包含哈希表中的值 |
Hashtable 类中的方法
下表中列出了 Hashtable 类中一些常用的方法:
方法名 | 描述 |
---|---|
public virtual void Add(object key, object value) | 向哈希表中添加一个带有指定的键和值的元素 |
public virtual void Clear() | 从哈希表中移除所有的元素 |
public virtual bool ContainsKey(object key) | 判断哈希表是否包含指定的键 |
public virtual bool ContainsValue(object value) | 判断哈希表是否包含指定的值 |
public virtual void Remove(object key) | 从哈希表中移除带有指定的键的元素 |
C# SortedList:排序列表
SortedList 类的中的属性
下表列出了 SortedList 类中一些常用的属性:
属性 | 描述 |
---|---|
Capacity | 获取或设置排序列表中可包含的元素个数 |
Count | 获取排序列表中的元素个数 |
IsFixedSize | 判断排序列表是否具有固定大小 |
IsReadOnly | 判断排序列表是否只读 |
Item | 获取或设置排序列表中指定键所关联的值 |
Keys | 获取一个包含排序列表中所有键的集合 |
Values | 获取一个包含排序列表中所有值的集合 |
SortedList 类的中的方法
下表列出了 SortedList 类中一些常用的方法:
方法名 | 描述 |
---|---|
public virtual void Add(object key, object value) | 向排序列表中添加一个带有指定的键和值的元素 |
public virtual void Clear() | 从排序列表中移除所有的元素 |
public virtual bool ContainsKey(object key) | 判断排序列表中是否包含指定的键 |
public virtual bool ContainsValue(object value) | 判断排序列表中是否包含指定的值 |
public virtual object GetByIndex(int index) | 获取排序列表中指定索引处的值 |
public virtual object GetKey(int index) | 获取排序列表中指定索引处的键 |
public virtual IList GetKeyList() | 获取排序列表中的键 |
public virtual IList GetValueList() | 获取排序列表中的值 |
public virtual int IndexOfKey(object key) | 返回排序列表中指定键的索引,索引从零开始 |
public virtual int IndexOfValue(object value) | 返回排序列表中指定值第一次出现的索引,索引从零开始 |
public virtual void Remove(object key) | 从排序列表中移除带有指定键的元素 |
public virtual void RemoveAt(int index) | 移除排序列表中指定索引处的元素 |
public virtual void TrimToSize() | 将排序列表的容量设置为排序列表中元素的实际个数 |
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _03_SortedList { internal class Program { static void Main(string[] args) { //SortedList 排序列表 //存储一系列按照键进行排序的键值对,可以通过键/索引访问这些键值对 //排序列表是数组和哈希表的组合,可以使用键或索引访问各项的列表 //如果使用索引访问各项,那么它就是一个动态数组(ArrayList),如果使用键访问各项,那么它就是一个哈希表(Hashtable) //集合中的各项总是按键值进行排序 SortedList sortedList = new SortedList(); sortedList.Add(10,"这是10"); sortedList.Add(5, "这是5"); //可以通过键进行访问 Console.WriteLine(sortedList[10]); Console.WriteLine(sortedList[5]); //通过索引进行访问,排序列表会自动根据键进行排序,因为第一个的键值5 Console.WriteLine(sortedList.GetByIndex(0));//这是5 Console.WriteLine(sortedList.GetByIndex(1));//这是10 sortedList[10] = "这是重新赋值之后的10"; Console.WriteLine(sortedList.GetByIndex(1)); Console.WriteLine(sortedList.Count); Console.WriteLine(sortedList.Keys); Console.WriteLine(sortedList.Values); //方法: sortedList.ContainsKey(10); sortedList.ContainsValue(5); sortedList.Remove(5);//根据键删除 sortedList.RemoveAt(1);//根据索引删除 sortedList.GetKey(1);//根据索引获取指定位置的键 sortedList.GetByIndex(1);//根据索引获取指定位置的值 } } }
C# Stack:堆栈
在 C# 中,堆栈(Stack)类表示一个后进先出的对象集合,当需要对项目进行后进先出的访问时,则可以使用堆栈。向堆栈中添加元素称为推入元素,从堆栈中移除元素称为弹出元素。
Stack 类中的属性
下表列出了 Stack 类中一些常用的属性:
属性 | 描述 |
---|---|
Count | 获取堆栈中包含的元素个数 |
IsSynchronized | 判断是否同步对堆栈的访问(线程安全) |
SyncRoot | 获取可用于同步对堆栈访问的对象 |
Stack 类中的方法
下表列出了 Stack 类中一些常用的方法:
方法名 | 描述 |
---|---|
public virtual void Clear() | 从堆栈中移除所有的元素 |
public virtual bool Contains(object obj) | 判断某个元素是否在堆栈中 |
public virtual object Peek() | 返回在堆栈顶部的对象,但不移除它 |
public virtual object Pop() | 移除并返回在堆栈顶部的对象 |
public virtual void Push(object obj) | 向堆栈顶部添加一个对象 |
public virtual object[] ToArray() | 复制堆栈到一个新的数组中 |
C# Queue:队列
在 C# 中,队列(Queue 类)与堆栈类似,它代表了一个先进先出的对象集合,当您需要对项目进行先进先出访问时,则可以使用队列。向队列中添加元素称为入队(enqueue),从堆栈中移除元素称为出队(deque)。
Queue 类中的属性
下表列出了 Queue 类的一些常用的属性:
属性 | 描述 |
---|---|
Count | 获取队列中包含的元素个数 |
IsSynchronized | 判断是否同步对队列的访问(线程安全) |
SyncRoot | 获取可用于同步对队列访问的对象 |
Queue 类中的方法
下表列出了 Queue 类的一些常用的方法:
方法名 | 描述 |
---|---|
public virtual void Clear() | 从队列中移除所有的元素 |
public virtual bool Contains(object obj) | 判断某个元素是否在队列中 |
public virtual object Dequeue() | 移除并返回在队列开头的对象 |
public virtual void Enqueue(object obj) | 向队列的末尾处添加一个对象 |
public virtual object[] ToArray() | 复制队列到一个新的数组中 |
public virtual void TrimToSize() | 将队列的容量设置为队列中元素的实际个数 |
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _04_Stack和Queue { internal class Program { static void Main(string[] args) { //堆栈(Stack)类表示一个后进先出的对象集合,当需要对项目进行后进先出的访问时,则可以使用堆栈。向堆栈中添加元素称为推入元素(入栈),从堆栈中移除元素称为弹出元素(出栈)。 //声明一个堆栈 Stack<String>stack = new Stack<String>(); //添加一个数据 stack.Push("吴亦凡"); stack.Push("李云迪"); stack.Push("罗志祥"); //删除一个数据(只能删除最后一个数据) stack.Pop(); //获取堆栈中最上层的数据 stack.Peek(); //清空堆栈 stack.Clear(); //将堆栈转化为数组 stack.ToArray(); //stack.Count; //队列(Queue 类)与堆栈类似,它代表了一个先进先出的对象集合,当需要对项目进行先进先出访问时,则可以使用队列。向队列中添加元素称为入队(enqueue),从堆栈中移除元素称为出队(deque)。 Queue<String> queue = new Queue<String>(); //入队 (添加) queue.Enqueue("凡凡"); queue.Enqueue("吴亦凡"); //出队 (删除) queue.Dequeue(); //获取最顶部的元素 queue.Peek(); queue.ToArray(); queue.Clear(); } } }
比较器
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _05_比较器 { internal class Program { static void Main(string[] args) { //高阶函数(高级函数):参数也是一个函数 //回调函数:以参数的形式,传递进函数内部的函数 // int[] ints= { 4,1, 2, 3 }; //有些数据的排序方法,需要自定义排序,需要传递一个比较器 //数组的Sort方法,可以传递一个lambda表达式作为比较器 Array.Sort(ints,(x,y)=>y-x); ArrayList list=new ArrayList() { 2,1,3}; //ArrayList 必须传递一个比较器实例 list.Sort(new MyComparer()); People[] peoples = new People[] { new People(){Name="吴亦凡",Age=20}, new People(){Name="罗志祥",Age=10}, new People(){Name="云嵩阳",Age=18}, }; //把peoples以每个人的年龄从小到大进行排序 Array.Sort(peoples,(x,y)=>x.Age-y.Age); ArrayList peopleList=new ArrayList(); peopleList.AddRange(peoples); //把peopleList以每个人年龄从小到大进行排序 peopleList.Sort(new AgeComparer()); foreach (var item in peopleList) { Console.WriteLine(((People)item).Name); } } class People { public string Name; public int Age; } //定义一个自己的比较器 //暂且: //IComparer:接口 //MyComparer:类 //MyComparer实现IComparer接口 class MyComparer : IComparer { //比较器需要实现一个比较方法 public int Compare(object x,object y)//固定写法 { return CaseInsensitiveComparer.Default.Compare(y,x); } } class AgeComparer : IComparer { public int Compare(object x, object y)//固定写法 { //需要将object类型转换为People类型,才能访问对应的属性 return ((People)y).Age - ((People)x).Age; } } } }
装箱和拆箱
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _06_装箱和拆箱 { internal class Program { static void Main(string[] args) { //装箱:是将值类型转换成引用类型的过程 //拆箱:是将引用类型转换成值类型的过程 int a = 1; object b = a;//装箱 object c = 1; int d = (int)c;//拆箱 ArrayList list=new ArrayList(); //装箱 list.Add(123); //拆箱 int i=(int)list[0]; //装箱:用于在垃圾回收堆中存储值类型,装箱是值类型到Object类型或到此类型所实现的任何接口类型的隐式转换 //拆箱:从object类型到值类型或从接口到实现该接口的值类型的显示转换 } } }