選擇合適的集合類別

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

程式碼如下:

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 介面。如果元素的型別是 string、int 等基礎型別,當然就沒問題,因為它們已經具備同類型物件互相比大小的功能。如果元素的型別是你自己定義的,例如 Employee、Student,你就得自行實作這些比較的方法。

字典集合(key-value pair)也有類似情形需要注意。字典集合是利用雜湊 (hash) 的方式來把物件存入多個小籃子裡面,而將來搜尋物件時,便利用雜湊值來快速找到物件所在的籃子(位置)。因此,你的自訂類別應該要改寫 GetHashCode() 和 Equals() 方法,才能讓這個雜湊機制有效運作。

對於需要執行緒安全的場合,亦即有多條執行緒會同時讀取和寫入同一個集合物件的元素,這裡就偷懶一下,沒有把挑選的邏輯寫出來,需要的朋友可參考原文

Post Comments

技術提供:Blogger.