【C#】常見容器介紹(ArrayList、List、HashSet、Hashtable 、Dictionary、Stack、Queue)

一、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<int> list = new List<int>() { 10, 40, 30, 20 };//聲明一個int類型集合,在聲明的時候直接初始化
            List<People> peoples = new List<People>();//聲明一個People類型集合,長度爲0

添加元素

            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

HashtableDictionary都是從一組鍵(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();//移除並返回位於隊列開始處的對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章