C#常见容器ArrayListListHashSetHashtable DictionaryStackQueue

Posted 小哈龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#常见容器ArrayListListHashSetHashtable DictionaryStackQueue相关的知识,希望对你有一定的参考价值。


一、ArrayList、List< T >列表和HashSet< T >哈希集


1.简单介绍及区别:


命名空间
System.Collections:ArrayList
System.Collections.Generic:List<T> 、 HashSet<T>

ArrayList:是一个使用大小会根据需要动态增加的数组,可以存储任意类型的数据,但是ArrayList存储的都是Object类型,很多时候在存取时需要强制类型转换,引起装箱和拆箱的操作,可能会影响效率。

List<T>泛型集合列表:用于存储某一种特定类型的数据,存储的数据可以重复,并且存储的数据是有序的,可以通过下标[]获取。用法在一定程度上比ArrayList更灵活、高效,可以说是最常用的一种容器。

HashSet<T>哈希集:与List一样用于存储一种特定类型的数据,区别是存储的数据不可以重复,会自动消除重复,并且其中存储的元素没有特定的顺序,不能通过下标[]访问。

2.List< T >简单用法举例:

辅助类:

 public class People
    
        public string name;
        public int age;
        public People(string _name, int _age)
        
            name = _name;
            age = _age;
        
    

创建:
可以在创建的时候初始化

添加元素:

list.Add(50);//Add默认将数据添加到结尾 结果:list =【10,40,30,20,50】
People[] data = new People[]  new People("小明", 10), new People("小李", 9), new People("小张", 12) ;
peoples.AddRange(data);//整体添加

排序、反转:
可以使用lambda表达式自定义特定类型排序方式

list.Sort();//升序  结果:list =【10,20,30,40,50】
list.Reverse();//将列表反转,无排序效果   结果:list =【50,40,30,20,10】
//lambda表达式对People类型排序
peoples.Sort((People a, People b) =>

    return a.age < b.age ? -1 : 1;//-1->a排前,1->a排后
);

查找、删除:

bool con = list.Contains(30);//是否包含,返回bool值
bool removeSuccess = list.Remove(20);//移除特定对象的第一个匹配项,删除成功返回true,否则返回false
list.RemoveAt(2);//删除指定索引处的元素


3.List< T >注意事项:赋值


赋值:赋值不当会造成项目里莫名其妙的数据异常           

List<int> oldList = new List<int>()  10, 20, 30, 40, 50, 60 ;//创建一个原始list集合
List<int> newList = oldList;//将创建的原始list集合赋值给另一个新List

newList.Remove(30);//新list删除30这个元素,此时oldList里的30元素也会被删除,因为oldList和newList指的是同一个集合
foreach(var it in oldList)

    Console.Write(it + "  ");

 Console.WriteLine("-----------------");
foreach (var it in newList)

    Console.Write(it + "  ");

Console.ReadKey();


二、Hashtable 哈希表和Dictionary字典


1.简单介绍及区别:


命名空间:
System.Collections:Hashtable
System.Collections.Generic:Dictionary

Hashtable和Dictionary都是从一组键(Key)到一组值(Value)的映射,其中存储的每一个元素都是一组键值对。并且存储的元素具有无序性,其中的每一个Key都必须是唯一且不允许为null,Key值不允许重复,Value在是引用类型的情况下可以为null。区别是Hashtable的键值都是object类型,存取强制转换会引起装箱拆箱操作,但是Dictionary可以自定义键值为什么类型,存取效率会高一写。

2.Dictionary简单用法举例:


创建,添加元素,删除:

Dictionary<int, string> dict = new Dictionary<int, string>();//创建,创建完后长度为0
dict.Add(1, "小张");//添加元素,保持key值唯一
dict.Add(2, "小李");
dict.Add(3, "小王");
dict.Add(4, "小何");
dict.Remove(3);//删除指定key值为3的元素

查找、取值、遍历:

bool contain = dict.ContainsKey(2);//是否包含指定key值的元素
string value = string.Empty;
bool getValue = dict.TryGetValue(2, out value);//获取与指定键关联的值,返回值如果true,则包含具有指定键的元素,值为Value,否则为false。
//遍历
foreach(KeyValuePair<int,string> item in dict)

    Console.WriteLine(item.Key + "  " + item.Value);//打印每个键值对的key和value


3.Dictionary注意事项:添加元素,取值,遍历时删除元素


添加元素、取值:

dict [ key ] = value
⇒ 当Dict里key值存在,表示修改value值,当key值不存在,表示添加<key,value>这个元素。
value = dict [ key ]
⇒ 当Dict里key值存在,合法,当key值不存在,不合法,抛异常,所以一般应该尽量避免这种写法。

dict.Add(1, "小张");//添加元素,保持key值唯一
dict.Add(2, "小李");
dict.Add(3, "小王");
dict.Add(4, "小何");
dict[5] = "小马";//当dict里含有5这个key时,这句话表示更改key值为5的value值,当dict里不含有5这个key值时,这句话表示添加<5,小马>这个键值对。
Console.WriteLine(dict[6]);//不合法,抛异常System.Collections.Generic.KeyNotFoundException:“给定关键字不在字典中。”


删除元素:
Dictionary里value值是可以重复的,假如需要删除dict里所有Value是小张的元素
一般情况是遍历删除,但是在遍历执行枚举操作时修改集合,会抛异常。
错误写法:

foreach(var item in dict)//遍历

    if (item.Value == "小张")//删除dict里所有vale值是小张的元素
    
        //抛异常,System.InvalidOperationException:“集合已修改;可能无法执行枚举操作。”
        dict.Remove(item.Key);
    


常规正确写法:
先找,保存所有key,再删

List<int> needRemoveKeys = new List<int>();
foreach(var item in dict)//遍历

    if (item.Value == "小张")//找到dict里所有vale值是小张的元素
    
        needRemoveKeys.Add(item.Key);//先保存key值
    

foreach(var it in needRemoveKeys)//遍历需要删除的key值集合,挨个删除

    dict.Remove(it);


三、Stack栈和Queue队列


1.简单介绍:


命名空间:
System.Collections:Stack、Queue
System.Collections.Generic:Stack<T>、Queue<T>

栈:表示对象的简单后进先出 (LIFO) 的集合,Stack为非泛型集合,Stack<T>为泛型集合。先放入栈的数据会被后调取。
队列:表示对象的先进先出(FIFO)集合,Queue为非泛型集合,Queue<T>为泛型集合。先放入队列的数据会被先调取。

2.简单用法举例:


栈:

Stack newStack = new Stack();//创建一个非泛型栈
newStack.Push(30);//在顶部插入一个对象
newStack.Push(20);//
newStack.Push(10);//此时newStack=30,20,10
IEnumerator enumerator = newStack.GetEnumerator();
while (enumerator.MoveNext())//枚举遍历

    Console.WriteLine(enumerator.Current);

int value1 = (int)newStack.Peek();//返回的对象顶部的数据而不删除它,取出后需要强制类型转换,此时newStack=30,20,10
int value2 = (int)newStack.Pop();//删除并返回顶部的数据,此时newStack=30,20

队列:

Queue<string> queue = new Queue<string>();//使用泛型队列创建一个存储string类型的队列
queue.Enqueue("小明");//将对象添加到队列的结尾处。
queue.Enqueue("小张");
IEnumerator queueEnumerator = queue.GetEnumerator();
while (queueEnumerator.MoveNext())//枚举遍历

    Console.WriteLine(queueEnumerator.Current);

string _value1 = queue.Peek();//返回位于队列开始处的对象但不将其移除。
string _value2 = queue.Dequeue();//移除并返回位于队列开始处的对象

原文链接:https://blog.csdn.net/qq_41468219/article/details/106391733

以上是关于C#常见容器ArrayListListHashSetHashtable DictionaryStackQueue的主要内容,如果未能解决你的问题,请参考以下文章

C#常见容器ArrayListListHashSetHashtable DictionaryStackQueue

(76)C#里怎么样选择各种通用类型容器

C#实现乞丐版IOC容器

常见的容器安全威胁都有哪些?

(76)C#里怎么样选择各种通用类型容器

如何使用 C# 连接到 Blob 存储容器