James Michael Hare 有一篇 C# 基礎文章:Choosing the Right Collection Class,整理了一些 .NET 集合類別的特性和適用時機,很值得參考。我嘗試用 if-then-else 語法寫了一個協助挑選集合類別的決策邏輯,也許將來碰到不知該選誰的時候可以派上用場。
[2018-02-12 更新]這裡有圖文版小抄: http://www.huanlintalk.com/2018/02/choosing-net-collection-types.html
程式碼如下:
另外要注意的是,所謂的自動排序,指的是元素插入集合或從集合中刪除時,順序會自動重排。但這個重新排序的動作能否 work,主要是看存入集合的元素的類別是否有實作「比較元素的方法或介面」,例如 IComparable 介面。如果元素的型別是 string、int 等基礎型別,當然就沒問題,因為它們已經具備同類型物件互相比大小的功能。如果元素的型別是你自己定義的,例如 Employee、Student,你就得自行實作這些比較的方法。
字典集合(key-value pair)也有類似情形需要注意。字典集合是利用雜湊 (hash) 的方式來把物件存入多個小籃子裡面,而將來搜尋物件時,便利用雜湊值來快速找到物件所在的籃子(位置)。因此,你的自訂類別應該要改寫 GetHashCode() 和 Equals() 方法,才能讓這個雜湊機制有效運作。
對於需要執行緒安全的場合,亦即有多條執行緒會同時讀取和寫入同一個集合物件的元素,這裡就偷懶一下,沒有把挑選的邏輯寫出來,需要的朋友可參考原文。
[2018-02-12 更新]這裡有圖文版小抄: http://www.huanlintalk.com/2018/02/choosing-net-collection-types.html
程式碼如下:
string ChooseCollectionClass() { if (不需要執行緒安全 || 只需要對集合進行讀取動作) { UsingNamespace("System.Collection.Generic"); if (儲存的資料是 key-value 形式) { if (必須自動排序好) { if (搜尋、新增、刪除元素的動作都要很快) { return "SortedDictionary<TKey, TValue>"; } else // 以搜尋為主,極少執行插入和刪除元素的動作 { return "SortedList<TKey, TValue>"; // SortedList 的搜尋速度很快,插入和刪除的速度比較慢. } } else // 元素不用排序 { return "Dictionary<TKey,TVale>"; } } else // 儲存的資料不是 key-value 形式. { if (元素在集合中必須是唯一,即不可重複) { if (需要自動排序好) { return "SortedSet<T>"; } else { return "HashSet<T>"; } } else if (必須要像陣列那樣,能夠用索引來存取元素) { if (需要自動排序好) { return "SortedList<T>"; } else { return "List<T>"; } } else // 不需要使用索引來存取元素 { if (存取元素的順序固定為先進先出) { return "Queue<T>"; } if (存取元素的順序固定為後進先出) { return "Stack<T>"; } if (需要頻繁且大量地插入和刪除元素) { return "LinkedList<T>"; } return "沒有你想要的!"; } } } else // 需要執行緒安全 { return ChooseFromNamespace("System.Collection.Concurrent"); } }
另外要注意的是,所謂的自動排序,指的是元素插入集合或從集合中刪除時,順序會自動重排。但這個重新排序的動作能否 work,主要是看存入集合的元素的類別是否有實作「比較元素的方法或介面」,例如 IComparable
字典集合(key-value pair)也有類似情形需要注意。字典集合是利用雜湊 (hash) 的方式來把物件存入多個小籃子裡面,而將來搜尋物件時,便利用雜湊值來快速找到物件所在的籃子(位置)。因此,你的自訂類別應該要改寫 GetHashCode() 和 Equals() 方法,才能讓這個雜湊機制有效運作。
對於需要執行緒安全的場合,亦即有多條執行緒會同時讀取和寫入同一個集合物件的元素,這裡就偷懶一下,沒有把挑選的邏輯寫出來,需要的朋友可參考原文。
沒有留言: