最全數據結構詳述: List VS IEnumerable VS IQueryable VS ICo

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

Complete Collection Comparison

 

Collection(集合)

Collection是數據記錄集合,

編寫代碼過程當中,經常須要合適的容器保存臨時數據,方便修改和查找,如何選取合適的數據容器,關鍵在於將執行的數據操做以及數據記錄是否大量。 數據庫

Array(數組)

特徵 數組

1. 固定大小,數組的大小是初始化時決定沒法修改的數值。 服務器

2. 強類型,存儲數據元素類型必須在初始化時指定,所以在運行時,不須要耗費額外的時間來定義數組類型,可以大大提高運行效率。 數據結構

3. 可以使用Foreach關鍵字實現數組迭代和查找。 app

由於數組大小是固定的,且是強類型數據結構,所以在運行時只佔用不多的內存,運行時效率很高。 dom

 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,>
相關文章
相關標籤/搜索