文章出處

本文對常用的數據結構詳述:Array, ArrayList,List,IList,ICollection, Stack, Queue, HashTable, Dictionary, IQueryable, IEnumerable。

Complete Collection Comparison

 

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,>

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()