本文對常用的數據結構詳述:Array, ArrayList,List,IList,ICollection, Stack, Queue, HashTable, Dictionary, IQueryable, IEnumerable。
Collection(集合)
Collection是數據記錄集合,
編寫代碼過程中,常常需要合適的容器保存臨時數據,方便修改和查找,如何選取合適的數據容器,關鍵在于將執行的數據操作以及數據記錄是否大量。
Array(數組)
特征
1. 固定大小,數組的大小是初始化時決定無法修改的數值。
2. 強類型,存儲數據元素類型必須在初始化時指定,因此在運行時,不需要耗費額外的時間來定義數組類型,能夠大大提升運行效率。
3. 可使用Foreach關鍵字實現數組迭代和查找。
因為數組大小是固定的,且是強類型數據結構,因此在運行時只占用很少的內存,運行時效率很高。
1: //It is obvious that strArray is
2: //1. string --> Strongly Type
3: //2. Sized=10 --> Fixed Size
4:
5: string[] strArray = new string[10];
6:
7: for (int i = 0; i < 10; i++)
8: {
9: if (strArray[i]==null)
10: {
11: strArray[i] = (i+1).ToString();
12: }
13: }
14:
15: this.ListBoxArray.DataSource = null;
16: this.ListBoxArray.Items.Clear();
17:
18: this.ListBoxArray.DataSource = strArray;
19: this.ListBoxArray.DataBind();
ArrayList
1. ArrayList 沒有固定的長度,容量可動態增加,可應用于開發人員無法確定數組元素個數等場景,當然這種情況下,在定義結構體的時候會非常耗時。
2. ArrayList 不是強類型,ArrayList中不同元素類型可以不相同,并且需要在運行時根據實際的輸入來確定元素類型。因此在運行時消耗內存較多。
3. 可使用Froeach 關鍵字操作ArrayList。
1: public class Product
2: {
3: public Product()
4: {
5:
6: }
7: public Product(string Code, string Name)
8: {
9: _Code = Code;
10: _Name = Name;
11: }
12:
13: public string _Code {get; set;}
14: public string _Name { get; set; }
15: }
ArrayList支持String,int,以及十進制小數類型。
1: //It is NOT obvious that strArrayList is 1. string? int? object? decimal? --> NOT Strongly Type
2: // 2. Sized=10? 20? 100? -->NOT Fixed Size
3: // Namespace: System.Collections
4:
5: System.Collections.ArrayList strArrayList = new System.Collections.ArrayList();
6: //System.Linq.IQueryable type of data is not specific runtime defered support
7: strArrayList.Add("Mahsa"); // "Mahsa": is string
8: strArrayList.Add(1); // 1 : is integer
9: strArrayList.Add(0.89); // 0.89: is decimal
10:
11: this.ListBoxArrayList.DataSource = null;
12: this.ListBoxArrayList.Items.Clear();
13: this.ListBoxArrayList.DataSource = strArrayList;
14: this.ListBoxArrayList.DataBind();
15:
16: System.Text.StringBuilder str= new System.Text.StringBuilder();
17:
18: foreach (var item in strArrayList)
19: {
20: str.Append(" , "+item);
21: }
22: this.lblArrayList.Text = str.ToString();
23:
24: //Below is old way to fill obj from product , in Arraylist you need to create more than one instance
25: // Product objProduct = new Product();
26: // objProduct.Code = "1001";
27: // objProduct.Name = "Chair";
28:
29: //It is NOT obvious that strArrayList is
30: //1. string? int? object? decimal? OR OBJECT?? --> NOT Strongly Type
31: //2. Sized=10? 20? 100? -->NOT Fixed Size
32: // Namespace: System.Collections
33:
34: System.Collections.ArrayList objArrayList = new System.Collections.ArrayList();
35:
36: objArrayList.Add(new Product("1001", "Chair"));
37: objArrayList.Add(new Product("1002", "Sofa"));
38: objArrayList.Add(new Product("1003", "Carpet"));
39:
40: this.DropDownListArrayListObject.DataSource = null;
41: this.DropDownListArrayListObject.Items.Clear();
42: this.DropDownListArrayListObject.DataSource = objArrayList;
43:
44: //* Finding among Object of Array List is difficult , you have to find your specific item by index
45: Product objTemp = (Product)objArrayList[0];
46: objArrayList.Remove(objTemp);
47: //*
48: this.DropDownListArrayListObject.DataTextField = "_Name";
49: this.DropDownListArrayListObject.DataValueField = "_Code";
50: this.DropDownListArrayListObject.DataBind();
51: this.GridViewArrayListObject.DataSource = objArrayList;
52: this.GridViewArrayListObject.DataBind();
HashTable(哈希表)
HashTable是一種定義關鍵字的數據結構體,使用哈希表查找數據非常方便,哈希表既不是強類型也不固定大小限制。
1: //It is NOT obvious that strArrayList is
2: //1. string? int? object? decimal? OR OBJECT?? --> NOT Strongly Type
3: //2. Sized=10? 20? 100? -->NOT Fixed Size
4: // Namespace: System.Collections
5: //Hashtable solve the problem in Arraylist when we are looking for specific item
6: //Hashtable dedicate a key for each item, then finding item is easier and faster
7:
8: System.Collections.Hashtable objHashTable = new System.Collections.Hashtable();
9:
10: objHashTable.Add("1001","Chair");
11: objHashTable.Add("1002", "Sofa");
12: objHashTable.Add("1003", "Carpet");
13:
14:
15: this.DropDownListHashTable.DataSource = null;
16: this.DropDownListHashTable.Items.Clear();
17: this.DropDownListHashTable.DataSource = objHashTable;
18: //* finding item is easier you just need to point to it by call its key
19: objHashTable.Remove("1002");
20: //*
21: this.DropDownListHashTable.DataTextField = "Value";
22: this.DropDownListHashTable.DataValueField = "Key";
23: this.DropDownListHashTable.DataBind();
Stack
棧是最典型的數據結構,棧具有優先級劃分的數據結構,棧為每個內容項定義優先級,表示每個Item入棧和出棧的優先順序。因此操作棧中的數據,需要先將數據push 到棧的頂部,需要刪除元素必須變成棧頂部,即要遵守后進先出(LIFO)的原則。
棧與哈希表一樣既不是強類型也不限制元素個數。
Push 操作
1: //Stack is LIFO: Last in First Out
2: System.Collections.Stack objStackPush = new System.Collections.Stack();
3:
4: //By Push method you can insert item at the top of the stack
5: objStackPush.Push("Mahsa");
6: objStackPush.Push("Hassankashi");
7: this.lblPop.Text = "";
8: this.ListBoxStack.DataSource = objStackPush.ToArray();
9: this.ListBoxStack.DataBind();
Pop操作
1: System.Collections.Stack objStackPop = new System.Collections.Stack();
2:
3: objStackPop.Push("Mahsa");
4: objStackPop.Push("Hassankashi");
5:
6: //By Pop method you can remove item from the top of the stack --> Last in First in
7: this.lblPop.Text = objStackPop.Pop().ToString();
8:
9: this.ListBoxStack.DataSource = objStackPop.ToArray();
10: this.ListBoxStack.DataBind();
Queue
Queue同棧一樣也是具有優先級定義的結構體,遵循的規則是先進先出(FIFO),既不是強類型也不具有固定的大小限制。
入隊操作
1: //Queue is FIFO: First in First Out
2: System.Collections.Queue objQueue = new System.Collections.Queue();
3:
4: //By Enqueue method you can insert item at the END of the Queue
5: objQueue.Enqueue("Mahsa");
6: objQueue.Enqueue("Hassankashi");
7: objQueue.Enqueue("Cosmic");
8: objQueue.Enqueue("Verse");
9:
10: this.lblQueue.Text = "";
11: this.ListBoxQueue.DataSource = objQueue.ToArray();
12: this.ListBoxQueue.DataBind();
出隊操作
1: System.Collections.Queue objQueue = new System.Collections.Queue();
2:
3: objQueue.Enqueue("Mahsa");
4: objQueue.Enqueue("Hassankashi");
5: objQueue.Enqueue("Cosmic");
6: objQueue.Enqueue("Verse");
7:
8: //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
9: this.lblQueue.Text=objQueue.Dequeue().ToString();
10:
11: this.ListBoxQueue.DataSource = objQueue.ToArray();
12: this.ListBoxQueue.DataBind();
入隊操作
1: System.Collections.Queue objQueue = new System.Collections.Queue();
2:
3: objQueue.Enqueue("Mahsa");
4: objQueue.Enqueue("Hassankashi");
5: objQueue.Enqueue("Cosmic");
6: objQueue.Enqueue("Verse");
7:
8: //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
9: this.lblQueue.Text=objQueue.Dequeue().ToString();
10:
11: this.ListBoxQueue.DataSource = objQueue.ToArray();
12: this.ListBoxQueue.DataBind();
List
什么情況下需要使用List?
1. List長度可不固定
2. 當數據為通用類型,List是強類型,List中元素類型不需要等到運行時來確定,這種特性使得List 運行時效率非常高。
3. 可使用Foreach關鍵字。
因為List不需要設定固定的大小,List靈活度高,且效率高常用于開發過程中。
1: //Like Array is Strong Type
2: //Like ArrayList with No Dimension
3: System.Collections.Generic.List<string> strList = new List<string>();
4:
5:
6: strList.Add("Mahsa");
7: strList.Add("Hassankashi");
8: strList.Add("Cosmic");
9: strList.Add("Verse");
10:
11: this.ListBoxListGeneric.DataSource = strList;
12: this.ListBoxListGeneric.DataBind();
13:
14: System.Text.StringBuilder str = new System.Text.StringBuilder();
15:
16: foreach (var item in strList)
17: {
18: str.Append(" , " + item);
19: }
20: this.lblList.Text = str.ToString();
IList
IList 繼承了List,包含多種方法的List接口。如果你無法判斷代碼改動的可能性,可以使用IList接口,減少模塊之間的依賴性。IList是接口因此無法被實例化,所以必須使用List來初始化。
1: System.Collections.Generic.IList<string> strIList = new List<string>();
我們一起了解一下具體的類和接口之間的區別。
1. 具體類可繼承其他類,并實現一個或多個接口。
2. 在內部類中可以定義變量并賦值,接口中不允許此操作。
3. 具體類可包含構造函數,而接口中不能定義構造函數
4. 抽象類中可包含訪問修飾符如public,private等,接口中不能包含。
1: //Ilist can not be instantiate from Ilist , so it should be instantiate from List
2: System.Collections.Generic.IList<string> strIList = new List<string>();
3:
4: strIList.Add("Mahsa");
5: strIList.Add("Hassankashi");
6: strIList.Add("Cosmic");
7: strIList.Add("Verse");
8:
9:
10: this.ListBoxListGeneric.DataSource = strIList;
11: this.ListBoxListGeneric.DataBind();
12:
13: System.Text.StringBuilder str = new System.Text.StringBuilder();
14:
15: foreach (var item in strIList)
16: {
17: str.Append(" , " + item);
18: }
19: this.lblList.Text = str.ToString();
IEnumerable
IEnumerable常用于遍歷集合元素,但是無法修改(刪除或添加)數據,使用IEnumberable 會從服務器端將所有數據拷貝到客戶端,并進行一定的過濾,如果服務器端有大量數據會造成內存負載超重。
1: //IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
2: System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee>
3: { new Employee { ID = 1001, Name="Mahsa"},
4: new Employee { ID = 1002, Name = "Hassankashi" },
5: new Employee { ID = 1003, Name = "CosmicVerse" },
6: new Employee { ID = 1004, Name = "Technical" }
7: };
8:
9:
10: this.GridViewIEnumerable.DataSource = empIEnumerable;
11: this.GridViewIEnumerable.DataBind();
12:
13: System.Text.StringBuilder str = new System.Text.StringBuilder();
14:
15: foreach (Employee item in empIEnumerable)
16: {
17: str.Append(" , " + item.ID +"-"+item.Name);
18: }
19:
20: this.lblIEnumerable.Text = str.ToString();
IQueryable
IQueryable與IEnumberable不同的是,當從服務器端加載過量的數據,IQueryable會自動減少應用負載。IQueryable可保證大數據量時應用程序的高性能。
IQueryable會先過濾數據,然后發送給客戶端。
1: DataAccessEntities ctx = new DataAccessEntities();
2: var ctx = new DataAccessEntities();
1: //Difference between IQueryable and IEnumerable
2:
3: //You can instantiate IEnumerable from List
4:
5: IEnumerable<employee> queryIEnumerable = new List<employee>() ;
6:
7:
8: //Bring ALL records from server --> to client then filter collection
9: //To bring all data from server you should omit where cluse from linq to sql
10: queryIEnumerable = from m in ctx.Employees select m;
11:
12: //If you use where as extension method with IEnumerable then All records will be loaded
13: queryIEnumerable = queryIEnumerable.Where(x => x.ID == 1).ToList();
14:
15:
16:
17: //You can not instantiate IQueryable
18:
19: IQueryable<employee> queryIQueryable=null;
20:
21: //Bring just ONE record from server --> to client
22:
23: queryIQueryable = (from m in ctx.Employees
24: where m.ID == 1
25: select m);
26:
27: //Whenever you call IQueryable so ==> It will be executed
28: this.GridViewIQueryable.DataSource = queryIQueryable.ToList();
29: this.GridViewIQueryable.DataBind();
30: </employee>
SQL Profiler:
如何追蹤查詢語句生成TSQL,生成需要的數據結構體:
Step 1:
Start -> MS SQL Server 2008 -> Performance Tools -> SQL Server Profiler
Step 2:
SQL Server Profiler -> File -> New Trace
Step 3:
輸入連接數據庫的用戶名和密碼
Step 4:
General (Tab) -> Use the Template: Standard
Step 5:
Event Selection (Tab) -> Event : TSQL -> Select : SQL-BatchCompleted | Select Show all Columns
Press Column Filter -> Database Name: Like: "DataAccess"
運行
Step 6:
查看結果
Step 7:
生成 IEnumerable數據 :
1: SELECT
2: [Extent1].[ID] AS [ID],
3: [Extent1].[Name] AS [Name],
4: [Extent1].[Age] AS [Age]
5: FROM [dbo].[Employee] AS [Extent1]
生成 IQueryable :
SELECT [Extent1].[ID] AS [ID], [Extent1].[Name] AS [Name], [Extent1].[Age] AS [Age] FROM [dbo].[Employee] AS [Extent1] WHERE 1 = [Extent1].[ID]
ICollection 繼承了IEnumberable,但是IEnumberable是基于索引的,ICollection不基于索引。
1: //IList {indexer and Modify} vs ICollection {randomly and Modify}
2: //Collection can not be instantiate from ICollection , so it should be instantiate from List
3: System.Collections.Generic.ICollection<string> strICollection = new List<string>();
4: strICollection.Add("Mahsa");
5: strICollection.Add("Hassankashi");
6:
7: //Countable***
8: int ICollectionCount=strICollection.Count;
9:
10: this.ListBoxICollection.DataSource = strICollection;
11: this.ListBoxICollection.DataBind();
12: System.Text.StringBuilder str = new System.Text.StringBuilder();
13: foreach (var item in strICollection)
14: {
15: str.Append(" , " + item);
16: }
17: this.lblICollection.Text = str.ToString();
18:
19: //IList***
20: System.Collections.Generic.IList<Employee> objIList = new List<Employee>();
21: objIList = (from m in ctx.Employees
22: select m).ToList();
23:
24: Employee obj = objIList.Where(i => i.Name == "Sara").FirstOrDefault();
25: int indexofSara= objIList.IndexOf(obj);
26: int cIList = objIList.Count;
27:
28: //ICollection***
29: System.Collections.Generic.ICollection<Employee> objICollection = new List<Employee>();
30: objICollection = (from m in ctx.Employees
31: select m).ToList();
32: Employee objIC = objICollection.Where(i => i.Name == "Sara").FirstOrDefault();
33: //You can not get index of object , if you clear comment from below code appears error
34: // int indexofSaraICollection = objIC.IndexOf(objIC);
35: int cICollection = objICollection.Count;
Stack Generic
入棧:
1: //Stack is LIFO: Last in First Out
2: //Here is for Push Stack in Generic
3: //System.Collections.Stack objStackPush = new System.Collections.Stack();
4: //Stack<T> can be instantiated from Stack<T>
5:
6: System.Collections.Generic.Stack<int> objStackPush = new System.Collections.Generic.Stack<int>();
7:
8: objStackPush.Push(1);
9: objStackPush.Push(2);
10:
11: this.lblPopGeneric.Text = "";
12: this.ListBoxStackGeneric.DataSource = objStackPush.ToArray();
13: this.ListBoxStackGeneric.DataBind();
出棧:
1: //Stack is LIFO: Last in First Out
2: //Here is for Pop Stack in Generic
3: //System.Collections.Stack objStackPop = new System.Collections.Stack();
4: //Stack<T> can be instantiated from Stack<T>
5:
6: System.Collections.Generic.Stack<int> objStackPop = new System.Collections.Generic.Stack<int>();
7:
8: objStackPop.Push(1);
9: objStackPop.Push(2);
10:
11: this.lblPop.Text = objStackPop.Pop().ToString();
12: this.ListBoxStack.DataSource = objStackPop.ToArray();
13: this.ListBoxStack.DataBind();
Queue Generic
入隊:
1: //Queue is FIFO: First in First Out
2: //Here is for Enqueue Queue in Generic
3: //System.Collections.Queue objQueue = new System.Collections.Queue();
4: //Queue<T> can be instantiated from Queue<T>
5:
6: System.Collections.Generic.Queue<int> objQueue = new System.Collections.Generic.Queue<int>();
7: objQueue.Enqueue(1);
8: objQueue.Enqueue(2);
9:
10: this.lblQueue.Text = "";
11:
12: this.ListBoxQueue.DataSource = objQueue.ToArray();
13: this.ListBoxQueue.DataBind();
出隊:
1: //Queue is FIFO: First in First Out
2: //Here is for Enqueue Queue in Generic
3: //System.Collections.Queue objQueue = new System.Collections.Queue();
4: //Queue<T> can be instantiated from Queue<T>
5:
6: System.Collections.Generic.Queue<int> objQueue = new System.Collections.Generic.Queue<int>();
7: objQueue.Enqueue(1);
8: objQueue.Enqueue(2);
9:
10: this.lblQueue.Text = "";
11:
12: this.ListBoxQueue.DataSource = objQueue.ToArray();
13: this.ListBoxQueue.DataBind();
Dictionary 及 IDictionary:
Dictionary 可通用,而哈希表不是通用的。Dictionary定義 <TKey,Tvalue>。IDictionary是Dictionary的接口,如果在后期開發中需要大量修改,建議使用IDictionary。
//Dictionary can instantiate from Dictionary , Dictionary is similar to Hashtable, //Dictionary is GENERIC but Hashtable is NON GENERIC //Such Hashtable you can find object by its key System.Collections.Generic.Dictionary<int, string=""> objDictionary = new Dictionary<int, string="">(); objDictionary.Add(1001, "Mahsa"); objDictionary.Add(1002, "Hassankashi"); objDictionary.Add(1003, "Cosmicverse"); string str = objDictionary[1002]; this.ListBoxDictionary.DataSource = objDictionary; this.ListBoxDictionary.DataBind();</int,>
文章列表
留言列表