目錄
一、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
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();//移除並返回位於隊列開始處的對象