各Collection陣列個別特性列表

  寫程式時,常會用到一些陣列來儲存資料,但什麼時候要用什麼樣的陣列,好像很少去想過這個問題,大多就直接的拿來就用,這裡整理了一下幾個陣列的特性及使用時機.

  寫程式時,常會用到一些陣列來儲存資料,但什麼時候要用什麼樣的陣列,好像很少去想過這個問題,大多就直接的拿來就用,這裡整理了一下幾個陣列的特性及使用時機.

 

一般常用的幾個陣列如下 :

1.ArrayList

2.Hashtable

3.HybridDictionary

4.ListDictionary

5.NameValueCollection

6.Queue

7.SortedList

8.Stack

9.StringCollection

10.StringDictionary

 

首先,先分幾個大方向,再來判斷說,你需要做到的功能,那幾個Collection可以做到,效能也較好.

需要做排序 :

ArrayList:繫結唯讀的排序資料到DataGrid上,如果只是要使用ArrayList的Indexes去繫結唯讀的資料,用ArrayList會比使用SortedList好,舉例來說,這資料要用來顯示在唯讀的DataGrid上,這資料已經檢索並排序好在ArrayList供顯示.

NameValueCollection:用在字串排序上.

SortedList:會在建立Collection時,就先排序好資料,所以在建立時是很耗效能在排序清單上,但是如果有少量資料異動或新增時,它會自己排序,其效能就會很好, SortedList適用在大部份是靜態也很少被異動的情況,也就是被排序的資料很少異動.

 

需要做搜尋 :

Hashtable:找尋隨機而具有Key/Value的資料.

StringDictionary:找尋隨機的字串資料.

ListDictionary:用在Size小於10的資料.

 

需要依Index去讀取每個Element的值 :

ArrayListStringCollection:可以用Index去取值.

Hashtable,SortedList,ListDictionary,StringDictionary:可以用Key的名字去取值.

NameValueCollection:可以用Index或是Key的名字去取值.

 

接下來再介紹這幾個陣列的特性.

ArrayList :

  可以動態依資料的新增,而去增加他的容量的大小,以下是它的幾個使用建議.

。儲存自定物件型別及資料變更頻繁,需要頻繁的插入及刪除.

。當資料異動完,使用TrimToSize去將ArrayList的容量調整到與實際資料一樣的大小,並對記憶體配置做調整,必需注意一點,在TrimToSize之後,盡量避免再去新增資料,因為ArrayList容量必需再動態變大,而Trim過後記憶體配置可能沒有空間拓大,記憶體會再重新配置,所以效能會比較差.

。儲存排序過後的資料與使用ArrayList.BinarySearch進行有效率的搜尋,排序與循序搜尋是使用耗資源的Contains方式.它是適用在一次性排序資料,如果需要頻繁的排序,那麼SortedList會比較有效率多了,因為當資料有異動時,它會自動重新排序.

。避免使用ArrayList去儲存String,String最好還是用StringCollection比較好.

 

Hashtable :

  使用一對Key/Value的方式來儲存資料,配置方式是依照雜湊值.

。適用在儲存大量的記錄及異動量低的資料,頻繁的異動資料,會因為重新計算雜湊值去跟其它資料進行比對的額外成本.

。Hashtable適用在頻繁的查詢資料,例如人員資料,UserNo就是Key,可以用這個Key去快速的找出Value.

 

HybridDictionary :

  汽車有油電混合系統,Collection也有混合版的,HybridDictionary當資料量小的時候,它可以像是ListDictionary的使用,如果量大,可以像Hashtable一樣新增容量.

。排序的資料,大部份的時間都不多,只有偶爾新增容量,如果確定資料很多或很少,就建議使用Hashtable與ListDicrionary.避免HybirdDictionary頻繁的在這兩種集合切換而造成的額外成本.

。適合頻繁的查詢資料.

。不要使用HybridDictionary來排序資料,它在排序的效能不好.

 

ListDictionary :

  建議使用在儲存少量的資料(少於10筆),因為它是使用單向連結串列來實作 IDictionary.在少於10筆的情況下,它會比Hashtable更小更快,如果大於10筆,就不應該使用ListDictionary.

 

NameValueCollection :

  使用String的Key與Value,所以可以用Key或者是Index來取值.

。可以排序Key/Value,而且Key值可以重覆.

。適用頻繁的異動資料.

。適合儲存需快速取出的資料.

 

Queue :

  先進先出FIFO的物件集合.

。適用依接收順序,循序讀取資料.

。因為FIFO的關係,所以在加入時,要注意順序.

。如果需要用String去讀取資料,最好是使用NameValueCollection.

 

SortedList :

  SortedList使用一對Key/Value的方式來儲存資料,所以可以依其索引及Key值進行存取,索引的順序是根據排序的順序,所以加入時,會依其排序加入到SortedList內,而Index也會相對應調整,所以當有資料異動時,它會較耗資源.

。適用在大部份是很少變動的資料.

。適用於使用Key或Index去快速取得排序後的資料.

。避免使用SortedList在大量異動的資料,其效能成本會很高,這情況之下,反而建議使用ArrayList.

。避免使用SortedList去排序String,這也會有額外的成本產生,建議使用StringCollection.

。因為排序的關係,通常在SortedList上進行的速度比Hashtable慢.

 

Stack :

  Stack跟Queue剛好相反,Stack是後進先出LIFO的方式.

。適合儲存LIFO的資料,例如:最近10個登入的人員.

。如果知道預計容量,在初始化時,最好就定義好大小,預設是10.

。適用在運作時,可以拋棄Item的情況.

。Stack適用在不需任意從陣列中讀取某一筆,只需LIFO的讀取.

 

StringCollection :

  StringCollection是Strongly typed的ArrayList,用來儲存String的陣列.

。用來儲存異動頻繁且大量的String資料.

。使用StringCollection去Binding String資料到DataGrid,可以避免在讀取時轉換為String的成本.

。不要使用StringCollection去排序字串或儲存預先排序好的資料.

 

StringDictionary :

  跟Hashtable一樣,Index與Value是強型別的String,而不是使用Object.

。適用在資料不需頻繁的異動,因為底層架構是Hashtable,使用來排序強型別的字串.

。用在儲存靜態的資料,頻繁搜尋的資料.

。如果是要儲存String,永遠記得使用StringDictionary比Hashtable好.

 

簡表 :

Type

描述

ArrayList

動態變動陣列的容量,當你在設計階段不知道它可能的容量時,ArrayList就很好用.

Hashtable

使用一對Key/Value的方式來儲存資料,配置方式是依照雜湊值.適用在搜尋上,而不適用在排序.

HybridDictionary

當資料量小的時候,它會使用ListDictionary,資料量大的時候,它會切換為Hashtable.

ListDictionary

在儲存10筆以下的Key/Value很好用.

NameValueCollection

String的Key/Value可以用來排序,可用Key或Index來存取資料.

Queue

先進先出FIFO的陣列.

SortedList

Key/Value的陣列,依Key排序及用Key或Index來存取資料.

Stack

後進先出LIFO的陣列.

StringCollection

強型別的String陣列

StringDictionary

跟Hashtable一樣,Index與Value是強型別的String,而不是使用Object.

 

 

  在.Net 1.1之後,在Collection有陸續的一些改善,之前有提到,Collection有泛型的Boxing/Unboxing問題,所以在.Net 2.0開始,就推出了一些改善過的Collection出來,在.Net 1.1所使用的namespace是System.Collections,新的是不同的namespace System.Collections.Generic.
 
Type
對應 無泛型 Type
描述
Hashtable
*加入的項目都是由值與關聯索引組成,用索引鍵讀取的效率高[接近O(1)],實作是雜湊資料表.
*Key不能Null,Value可以為Null
 
* HashSet只有一個值,這個集合沒有特定順序,也不可重覆,容量會自動增加.
*如果Count小於內部陣列容量,採O (1)計算,如果必需要調整HashSet大小,則是採O (n)
*Comparer/Contains的效能很好,是O (1)運算
 
*插入/移除/Count都是O (1)運算,所以效能很好.
*唯一支援多執行緒的讀取.
*資料可重覆.
*因為是雙向連結串列,因此每個節點都向前指向Next,向後指向Previous
*接受Null
ArrayList
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下,List<T>的效能較ArrayList好,且型別安全.
*執行BinarySearch前,要先排序.
*接受Null
Queue
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下, Queue <T>的效能較Queue好,且型別安全.
 
* SortedDictionary<TKey, TValue>用的記憶體比SortedList<TKey,TValue>多.
* SortedDictionary<TKey, TValue>對未排序資料做新增移除比SortedList<TKey,TValue>快.
* SortedDictionary<TKey, TValue>從排序的資料做一次性新增比
SortedList<TKey,TValue>慢.
SortedList
Stack
*這兩個型別的行為相同,最主要的差別在泛型.
*在大多數的情況下, Queue <T>的效能較Queue好,且型別安全.

 其它參考 :

Generic Collections

When to Use Generic Collections