文章目录
- C# 中的集合类型
- C# Dictionary 字典
- C# Hashtable:哈希表
- Hashtable 类中的属性
- Hashtable 类中的方法
- C# SortedList:排序列表
- SortedList 类的中的属性
- SortedList 类的中的方法
- C# Stack:堆栈
- Stack 类中的属性
- Stack 类中的方法
- C# Queue:队列
- Queue 类中的属性
- Queue 类中的方法
- 比较器
- 装箱和拆箱
- 上期习题答案
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) | 队列代表了一个先进先出的对象集合。 当您需要对各项进行先进先出的访问时,则可以使用队列。为队列中添加项目称为入队,为队列中移除项目称为出队。 |
ArrayList动态数组 List泛型集合详解在本专栏上期
C# Dictionary 字典
using System;
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.只能存储固定类型的数据,长度不固定
//ArrayList List Array使用索引进行数据的操作,字典使用"键"进行数据的操作
//键: 标识 在一个字典中键是唯一的 且不能为null
//格式:Dictionary<键的数据类型,值的数据类型> keyValuePairs = new Dictionary<键的数据类型,值的数据类型>();
Dictionary<string,int> keyValuePairs = new Dictionary<string, int>()
{
{ "Name",555},
{ "K",3455},
//键是在运行期间校验
//{ "K",345}//运行报错,已添加了具有相同键的项。
};
//向字典中添加数据
keyValuePairs.Add("刘亦菲", 999);
//通过键来获取值
//获取值
Console.WriteLine(keyValuePairs["Name"]);//555
//通过键来修改值
keyValuePairs["K"] = 234;
Console.WriteLine(keyValuePairs["K"]);
//表示字典中存储的个数
Console.WriteLine(keyValuePairs.Count);
//判断字典中是否拥有指定的键
Console.WriteLine(keyValuePairs.ContainsKey("K"));
//判断字典中是否拥有指定的值
Console.WriteLine(keyValuePairs.ContainsValue(999));
//字典一般用于一些信息的记录,用字典存储的数据,`可以加快查询的速度
}
}
}
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",2},
};
hashtable.Add("洛", 1);
hashtable.Add( 1,"刘某");
//values 获取哈希表中所有的值
Console.WriteLine(hashtable.Values);
//keys 获取hash表中所有的键
Console.WriteLine(hashtable.Keys);
//count 获取hash表中元素的个数
Console.WriteLine(hashtable.Count);
//注意:因为Hash表中,所有的数据类型都是不固定的,因此在遍历key或者value 只能标注为var/object类型
foreach (var key in hashtable.Keys)
{
Console.WriteLine(key);
}
Console.WriteLine("--------------------------");
//哈希表也可以用索引进行数据的获取和设置
Console.WriteLine(hashtable[1]);
hashtable[0] = 978;
//判断哈希表中是否拥有指定的值
Console.WriteLine(hashtable.ContainsValue("1"));
//判断哈希表中是否拥有指定的键
Console.WriteLine(hashtable.ContainsKey("1"));
//移除带有指定键的元素
hashtable.Remove(0);
//清空Hash表
hashtable.Clear();
}
}
}
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.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),从堆栈中移除元素称为出队(dequene)。
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)
{
// 高阶函数(高级函数):参数也是一个函数 如Find() Sort() 数组.Average()
// 回调函数:以参数的形式,传递进函数内部的函数
int[] ints = { 4,1, 2, 3 };
//有些数据的排序方法,需要自定义排序,需要传递一个比较器
//数组的sort方法,可以传递一个lambda表达式作为比较器
Array.Sort(ints,(x,y)=>y-x);
//这里的Array.Sort()就是一个高阶函数,(x,y)=>y-x是一个回调函数
ArrayList arrayList = new ArrayList() { 2,1,3};
//ArrayList 用Sort 必须传递一个比较器实例
arrayList.Sort(new MyComparer());
foreach(int x in arrayList) { Console.WriteLine(x); }
People[] peoples = new People[]
{
new People(){Name="牛头",Age=2131 },
new People(){Name="马面",Age=2133},
new People(){Name="驴嘴",Age=2533},
};
//把proples以每个人的年龄从小到大进行排序
Array.Sort(peoples, (x, y) => x.Age - y.Age);
ArrayList peoplelist = new ArrayList();
peoplelist.AddRange(peoples);
//把peoplelist 以每个人的年龄从大到小进行排序
peoplelist.Sort(new ListComparer());
foreach(People people in peoplelist) { Console.WriteLine(people.Name); }
}
//定义一个自己的比较器
//暂且:
//IComparer 接口
//ListComparer 类
//ListComparer实现IComparer接口
class ListComparer : IComparer
{
public int Compare(object x, object y)//固定写法
{
//这里只用y.Age无法访问,因为ArrayList存储的时候
//把People类数据转换为object类,所以使用时要进行强制转换
return ((People)y).Age - ((People)x).Age;
}
}
class MyComparer : IComparer
{
public int Compare(object x, object y)
{
return CaseInsensitiveComparer.Default.Compare(y, x);
}
}
//这里自定义类写到了Program类中,这是可以的,因为可以在类中定义类
//但严格的规范是类应该写到命名空间内
class People
{
public int Age;
public string Name;
}
}
}
装箱和拆箱
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('a');
//拆箱
char i = (char)list[0];
i='\0';
Console.WriteLine(i);
}
}
}
上期习题答案
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _01_上期习题答案
{
internal class Program
{
static void Main(string[] args)
{
People[] peoples =
{
new People {Name="吴亦凡",Age=18,Sex=People.ESex.man},
new People {Name="郑爽",Age=22,Sex=People.ESex.woman},
new People {Name="李云迪",Age=21,Sex=People.ESex.man},
new People {Name="蔡徐坤",Age=32,Sex=People.ESex.man},
new People {Name="权志龙",Age=8,Sex=People.ESex.man},
new People {Name="杨幂",Age=18,Sex=People.ESex.woman}
};
//1.查询peoples中所有的男性
//People[] ps1 = Array.FindAll(peoples, FindAllMan);
// bool FindAllMan(People p)
//{
// return p.Sex == People.ESex.man;
//}
//Func<People, bool> fn = p => p.Sex == People.ESex.man;
People[] ps2 = Array.FindAll(peoples, p => p.Sex == People.ESex.man);
//2.查询peoples中第一个女性
People p3 = Array.Find(peoples, FindFirstWoman);
People p4 = Array.Find(peoples, p => p.Sex == People.ESex.woman);
//3.判断数组中是否全部都是成年人
Console.WriteLine(Array.TrueForAll(peoples, Find18));
Console.WriteLine(Array.TrueForAll(peoples, p => p.Age >= 18));
//4.计算所有人的年龄的平均值
int allAge = 0;
foreach (People p in peoples)
{
Console.WriteLine(p.Age);
allAge += p.Age;
}
Console.WriteLine("平均值:" + (double)allAge / peoples.Length);
int[] ints = new int[] { 1, 2, 3 };
//计算数组的平均值
Console.WriteLine(ints.Average());
//People 不能直接计算,需要专递一个转换方法,把People变成数字让他计算
Console.WriteLine(peoples.Average(PeopleInt));
Console.WriteLine(peoples.Average(p=>p.Age));
//5.查询所有人中第一个未成年的男性
People child = Array.Find(peoples, FindChild);
People child2 = Array.Find(peoples, p => p.Age < 18 && p.Sex == People.ESex.man);
//-----------------------------
//ArrayList list = new ArrayList();
//foreach (int i in new int[5])
//{
// list.Add(Convert.ToDouble(Console.ReadLine()));
//}
//double sum = 0.0;
//for (int i = 0; i < list.Count; i++)
//{
// //list[i] 取出ArrayList里面的每一个值(object)
// sum +=(double)list[i];
//}
//Console.WriteLine("平均数是:{0}", sum / list.Count);
//ArrayList list = new ArrayList();
1,2,4,1,
//Random rd = new Random();
//for (int i = 0; i < 10; i++)
//{
// int num = rd.Next(10);
// //先list里面添加之前,判断list里面是否有当前生成的随机数
// if (!list.Contains(num))
// {
// //说明没有,需要添加
// list.Add(num);
// }
// else
// {
// //说明当前生成的随机数,在list中已经存在,不能添加,而且需要让for重新执行一次
// i--;
// }
//}
//while (list.Count!=10)
//{
//}
//int[] num = new int[] { 1, 3, 5, 6, 8, 100, 20, 11 };
泛型 也可以使用ArrayList
//List<int> Jilist = new List<int>();
//List<int> Oulist = new List<int>();
//for (int i = 0; i < num.Length; i++)
//{
// if (num[i] % 2 == 0)
// {
// Oulist.Add(num[i]);
// }
// else
// {
// Jilist.Add(num[i]);
// }
//}
//Jilist.AddRange(Oulist);
//for (int i = 0; i < Jilist.Count; i++)
//{
// Console.Write(Jilist[i] + " ");
//}
//Console.WriteLine("请输入一个字符串:");
//string str = Console.ReadLine();
//List<char> list = new List<char>();
//foreach (char ch in str)
//{
// list.Add(ch);
//}
//char[] c = list.ToArray();
//for (int i = 0; i < c.Length; i++)
//{
// Console.Write(c[i] + "-");
//}
string[] stringArray = { "aaa", "bbb", "aaa", "ccc", "bbb", "ddd", "ccc", "aaa", "bbb", "ddd" };
//List用于存储从数组里取出来的不相同的元素
List<string> listString = new List<string>();
foreach (string eachString in stringArray)
{
if (!listString.Contains(eachString))
listString.Add(eachString);
}
//最后从List里取出各个字符串进行操作
foreach (string eachString in listString)
{
Console.Write(eachString); //打印每个字符串
}
}
static public bool FindAllMan(People p)
{
return p.Sex == People.ESex.man;
}
static public bool FindFirstWoman(People p)
{
return p.Sex == People.ESex.woman;
}
static public bool Find18(People p)
{
return p.Age >= 18;
}
static public int PeopleInt(People p)
{
return p.Age;
}
static public bool FindChild(People p)
{
return p.Age < 18 && p.Sex == People.ESex.man;
}
}
class People
{
public enum ESex
{
man,
woman
}
public string Name { get; set; }
public int Age { get; set; }
public ESex Sex { get; set; }
}
}
觉得文章还不错,可以点赞,关注,评论,主页有C#教程专栏,欢迎上车!!!