常用的数据结构包括动态数组(ArrayList)、堆栈(Stack)、队列(Queue)和哈希表(Hashtable),这些集合类型都是C#为我们封装好的类型,需要引入命名空间 System.Collections 。
本质是一个object类型的有序数组,数据存取可能存在装箱拆箱问题,耗费性能。
static void Main(string[] args)
{
ArrayList array = new ArrayList();
#region 增
array.Add(1);//Add:将object类型的对象添加到ArrayList的结尾处
array.Add("123");
array.Add(true);
array.Add(new object());
array.Add(new Program());
ArrayList array2 = new ArrayList();
array.AddRange(array2);//AddRange:将ICollection的元素添加到ArrayList的末尾
array.Insert(1, "123456789");//Insert:将元素插入ArrayList的指定索引处
Console.WriteLine(array[1]);//输出:123456789
#endregion
#region 删
array.Remove(1);//Remove:从ArrayList中移除特定对象的第一个匹配项
array.RemoveAt(2);//RemoveAt:移除ArrayList的指定索引处的元素
array.Clear();//Clear:从ArrayList中移除所有元素
#endregion
array.Add(1);
array.Add("1234");
array.Add(true);
array.Add(true);
#region 查
Console.WriteLine(array[0]);//输出:1 ||指定ArrayList索引位置进行读取,索引位置不存在抛异常
if(array.Contains("1234"))//Contains:确定某元素是否在ArrayList中
{
Console.WriteLine("存在1234");//输出
}
int index = array.IndexOf(true);//IndexOf:搜索指定object并返回整个内的第一个匹配项的从零开始索引ArrayList,找不到返回-1
Console.WriteLine(index);//输出:2
Console.WriteLine(array.IndexOf(false));//输出:-1
index = array.LastIndexOf(true);//LastIndexOf:在整个ArrayList中搜索指定的object,并返回最后一个匹配项的从零开始的索引,否则返回-1
Console.WriteLine(index);//输出:3
#endregion
#region 改
Console.WriteLine(array[0]);//输出:1
array[0] = "999";//指定ArrayList索引位置进行更改,索引位置不存在抛异常
Console.WriteLine(array[0]);//输出:999
#endregion
#region 遍历
Console.WriteLine(array.Count);//Count:获取ArrayList中实际包含的元素数
Console.WriteLine(array.Capacity);
//Capacity:ArrayList可包含的元素数,俗称容量
//方式一:通过下标索引进行遍历
for(int i = 0; i < array.Count; i++)
{
Console.WriteLine(array[i]);//每次分别输出:999 1234 True True
}
//方式二:迭代器遍历
foreach (object item in array)
{
Console.WriteLine(item);//每次分别输出:999 1234 True True
}
#endregion
Console.ReadLine();
}
Stack是一种先进后出的数据结构,它的本质也是object[]数组,只是封装了特殊的存储规则
static void Main(string[] args)
{
Stack stack = new Stack();
#region 增
stack.Push(1);//Push:在Stack的顶部插入一个对象
stack.Push("123");
stack.Push(true);
stack.Push(1.2f);
stack.Push(new object());
#endregion
#region 取
object v = stack.Pop();//Pop:删除并返回Stack顶部的对象,Stack无元素时抛异常
Console.WriteLine(v);//输出:System.Object
v = stack.Pop();
Console.WriteLine(v);//输出:1.2
#endregion
#region 查
v = stack.Peek();//Peek:返回的对象顶部的Stack而不删除它,Stack无元素时抛异常
Console.WriteLine(v);//输出:true
v = stack.Peek();
Console.WriteLine(v);//输出:true
if(stack.Contains("123"))//Contains:确定某元素是否在Stack中
{
Console.WriteLine("存在123");//存在
}
#endregion
#region 改/删
//栈无法直接改变其中的某个元素 只能压栈(存)和弹栈(取)
stack.Clear();//Clear:从Stack中移除所有对象
//删除所有对象后重新加入达到所谓“改”的效果
stack.Push("1");
stack.Push(2);
stack.Push("哈哈");
#endregion
#region 遍历
Console.WriteLine(stack.Count);//Count:获取Stack中包含的元素数
//遍历顺序也是从栈顶到栈底的顺序
//方式一:迭代器遍历
foreach (object item in stack)
{
Console.WriteLine(item);//每次分别输出:哈哈 2 1
}
//方式二:转化为object数组
object[] array = stack.ToArray();
for(int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);//每次分别输出:哈哈 2 1
}
//方式三:循环弹栈
while(stack.Count > 0)
{
object o = stack.Pop();
Console.WriteLine(o);//每次分别输出:哈哈 2 1
}
#endregion
Console.ReadLine();
}
Queue是一种先进先出的数据结构,它的本质也是object[]数组,只是封装了特殊的存储规则。
static void Main(string[] args)
{
Queue queue = new Queue();
#region 增
queue.Enqueue(1);//Enqueue:将对象添加到Queue的末尾处
queue.Enqueue("123");
queue.Enqueue(1.4f);
queue.Enqueue(new Program());
#endregion
#region 取
object v = queue.Dequeue();//Dequeue:移除并返回位于Queue开始处的对象,Queue无元素时抛异常
Console.WriteLine(v);//输出:1
v = queue.Dequeue();
Console.WriteLine(v);//输出:123
#endregion
#region 查
v = queue.Peek();//Peek:返回位于Queue开始处的对象但不将其移除,Queue无元素时抛异常
Console.WriteLine(v);//输出:1.4
v = queue.Peek();
Console.WriteLine(v);//输出:1.4
if(queue.Contains(1.4f))//Contains:确定某元素是否在Queue中
{
Console.WriteLine("队列中存在1.4f");//输出
}
#endregion
#region 改/删
//队列无法直接改变其中的某个元素 只能进(存)和出(取)
queue.Clear();//Clear:从Queue中移除所有对象
//删除所有对象后重新加入达到所谓“改”的效果
queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
#endregion
#region 遍历
Console.WriteLine(queue.Count);//Count:获取Queue中包含的元素数
//方式一:迭代器遍历
foreach(object item in queue)
{
Console.WriteLine(item);//每次分别输出:1 2 3
}
//方式二:转化为object数组
object[] array = queue.ToArray();
for(int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);//每次分别输出:1 2 3
}
//方式三:循环取出
while(queue.Count > 0)
{
object o = queue.Dequeue();
Console.WriteLine(o);//每次分别输出:1 2 3
}
Console.WriteLine(queue.Count);//输出:0
#endregion
Console.ReadLine();
}
Hashtable(又称散列表、散列表)是基于键的哈希代码组织起来的 键/值对,使用键来访问集合中的元素,主要作用是提高数据查询的效率。Hashtable中的每个元素都是一个存储在DictionaryEntry对象中的键值对,且不是按顺序存储的。
static void Main(string[] args)
{
Hashtable hashtable = new Hashtable();
#region 增
hashtable.Add(1, "123");//Add:将带有指定键和值的元素添加到Hashtable中,注意这里的添加的键是唯一的,不能重复添加
hashtable.Add("123", 2);
hashtable.Add(true, false);
hashtable.Add(false, true);
hashtable[11] = 20;//直接赋值添加
#endregion
#region 删
hashtable.Remove(1);//Remove:从Hashtable中移除带有指定键的元素
hashtable.Remove(2);//移除不存在的键时,不会抛异常
hashtable.Clear();//Clear:从Hashtable中移除所有元素
#endregion
hashtable.Add(1, "123");
hashtable.Add(2, "1234");
hashtable.Add(3, true);
hashtable.Add("123456", 12);
hashtable[11] = 20;
#region 查
Console.WriteLine(hashtable[2]);//输出:1234 通过键进行查找
Console.WriteLine(hashtable[4]);//输出: 通过查找不存在的键时,不会抛异常返回“”
if (hashtable[1] != null)
{
Console.WriteLine("hashtable存在:" + hashtable[1]);//输出:hashtable存在:123
}
if(hashtable.Contains(2))
{
Console.WriteLine("存在键为2的键值对");//输出
}
if(hashtable.ContainsKey(3))
{
Console.WriteLine("存在键为3的键值对");//输出
}
if(hashtable.ContainsValue("1234"))
{
Console.WriteLine("存在值为1234的键值对");//输出
}
#endregion
#region 改
//只能改 键对应的值内容 无法修改键
Console.WriteLine(hashtable[1]);//输出:123
hashtable[1] = 200;
Console.WriteLine(hashtable[1]);//输出:200
Console.WriteLine(hashtable[11]);//输出:20
#endregion
#region 遍历
Console.WriteLine(hashtable.Count);//Count:获取包含在Hashtable中的键/值对的数目
//方式一:遍历哈希表中的所有键值对的键
foreach(object item in hashtable.Keys)
{
Console.WriteLine(item + ":" + hashtable[item]);//每次分别输出:123456:12 11:20 3:True 2:1234 1:200
}
//方式二:遍历哈希表中的所有键值对的值
foreach(object item in hashtable.Values)
{
Console.WriteLine(item);//每次分别输出:12 20 True 1234 200
}
//方式三:遍历哈希表中的所有键值对
foreach(DictionaryEntry item in hashtable)
{
Console.WriteLine(item.Key + ":" + item.Value);//每次分别输出:123456:12 11:20 3:True 2:1234 1:200
}
//方式四:迭代器遍历法
IDictionaryEnumerator idEnumerator = hashtable.GetEnumerator();
bool flag = idEnumerator.MoveNext();
while(flag)
{
Console.WriteLine(idEnumerator.Key + ":" + idEnumerator.Value);//每次分别输出:123456:12 11:20 3:True 2:1234 1:200
flag = idEnumerator.MoveNext();
}
#endregion
Console.ReadLine();
}
四个常用的集合类型的存储都会涉及装箱拆箱问题,会消耗性能。
当往其中进行值类型存储时就是在装箱,当将值类型对象取出来并转换使用时,就是存储拆箱。
例如:
ArrayList array = new ArrayList();
int j = 1;
array[0] = j;//装箱:值类型->object
j = (int)array[0];//拆箱:object -> 值类型
因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。